I'm getting confused.
MF_POPUP
0x00000010L
Specifies that the menu item opens a drop-down menu or submenu. The
uIDNewItem parameter specifies a handle to the drop-down menu or
submenu. This flag is used to add a menu name to a menu bar, or a menu
item that opens a submenu to a drop-down menu, submenu, or shortcut
menu.
(https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-appendmenua)
Yes, but how do we now specify the uID of the Menu and refer to it in the WindowProcedure,
if the uIDNewItem parameter is now a handle to the drop-down menu or submenu.
This is a simple code sample you can refer,
#include <Windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define EXIT_ID 1
#define SUB_ID 2
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message)
{
case WM_CREATE:
{
HMENU hMenubar = CreateMenu();
HMENU hFileMenu = CreateMenu(); //file is a regular menu.. Exit is a regular sub-menu..
HMENU hDisplayMenu = CreatePopupMenu(); //display is a popup-menu because it has children.
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFileMenu, "File");
AppendMenu(hFileMenu, MF_STRING | MF_POPUP, (UINT_PTR)hDisplayMenu, "Display");
AppendMenu(hDisplayMenu, MF_STRING, SUB_ID, "Sub");
AppendMenu(hFileMenu, MF_STRING, EXIT_ID, "Exit");
SetMenu(hwnd, hMenubar);
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case SUB_ID:
MessageBox(hwnd, "You click Sub menu", " ", MB_OK);
break;
case EXIT_ID:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// TODO: Add any drawing code that uses hdc here...
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
};
HINSTANCE hinst;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
HWND hwnd;
hinst = GetModuleHandle(NULL);
// create a window class:
WNDCLASS wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = "win32";
// register class with operating system:
RegisterClass(&wc);
// create and show window:
hwnd = CreateWindow("win32", "My program", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 0, 0, 1000, 800, NULL, NULL, hinst, NULL);
if (hwnd == NULL) {
return 0;
}
ShowWindow(hwnd, SW_SHOW);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Debug:
EXIT_ID and SUB_ID are the uID of the submenu. You need to define them manually.
#define EXIT_ID 1
#define SUB_ID 2
Updated:
You can use WM_MENUSELECT to get the handle to the menu that is clicked and compare their hmenus.
Sent to a menu's owner window when the user selects a menu item.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HMENU hMenubar;
switch (message)
{
case WM_CREATE:
{
hMenubar = CreateMenu();
HMENU hFileMenu = CreateMenu(); //file is a regular menu.. Exit is a regular sub-menu..
AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hFileMenu, L"File");
SetMenu(hWnd, hMenubar);
}
break;
case WM_MENUSELECT:
{
HMENU hmenu = (HMENU)lParam;
if (hmenu == hMenubar)
{
MessageBox(hWnd, L"You click main menu", L" ", MB_OK);
}
}
break;
...
Like this,
Related
I want one part of a window to display an image with a certain opacity while the other part to work as normal. Both parts shouldn't pass clicks through.
I have tried making the main window a certain colour then using SetLayeredWindowAttributes to make that colour transparent(so only the client area is transparent). Then having a child window over it with my translucent image. However the clicks pass through the window(even though I don't have WS_EX_TRANSPARENT). Alphablend doesn't seem to works since the bitmap isn't 32bmp. So now I am trying to use updatelayeredwindows but I am having trouble setting the region to update it.
case WM_CREATE:
hbmp = (HBITMAP)LoadImageA(NULL, "courtyard.bmp", IMAGE_BITMAP, 1920, 1080, LR_LOADFROMFILE);
HDC hdc = CreateCompatibleDC(NULL);
HBITMAP hbmp_old = (HBITMAP)SelectObject(hdc, hbmp);
POINT dcOffset = {0, 0};
SIZE size = {600, 395};
BLENDFUNCTION bf = {AC_SRC_OVER, 0, 100, 0};
RECT wrect;
GetClientRect(hwnd, &wrect);
wrect.top = wrect.top + 43;
UPDATELAYEREDWINDOWINFO info = {sizeof(info), GetDC(NULL), NULL, &size, hdc, &dcOffset, 0, &bf, ULW_ALPHA, &wrect};
UpdateLayeredWindowIndirect(hwnd, &info);
SelectObject(hdc, hbmp_old);
DeleteDC(hdc);
DeleteObject(hbmp);
HWND hbutton = CreateWindowExA(0,
"BUTTON",
"X",
WS_VISIBLE | WS_CHILD | BS_FLAT,
10,
10,
100,
100,
hwnd,
(HMENU)NULL,
NULL,
(LPVOID)NULL);
break;
The parts out of wrect are just a black translucent colour.
Here is my main window:
hwnd = CreateWindowExA(WS_EX_OVERLAPPEDWINDOW | WS_EX_LAYERED,
window_name,
window_title,
WS_OVERLAPPEDWINDOW,
(monitor_dimension.width - window_width) / 2,
(monitor_dimension.height - window_height) / 2 - 75,
window_width,
window_height,
(HWND)NULL,
(HMENU)NULL,
hInstance,
(LPVOID)NULL);
I get the result using SetLayeredWindowAttributes(hWnd, RGB(255, 0, 0), 0, LWA_COLORKEY); without manifest and the clicks don't pass through.
The following code adapted from SetLayeredWindowAttributes() causes mouse clicks to go through after minimizing window | WinAPI.
// WindowsProject2.cpp : Defines the entry point for the application.
//
#include "framework.h"
#include "WindowsProject2.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
// Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WINDOWSPROJECT2, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT2));
MSG msg;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT2));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT2);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hWnd, RGB(255, 0, 0), 0 /*doesn't matter*/, LWA_COLORKEY);
HWND hbutton = CreateWindowExA(0,
"BUTTON",
"X",
WS_VISIBLE | WS_CHILD | BS_FLAT,
10,
10,
100,
100,
hWnd,
(HMENU)NULL,
NULL,
(LPVOID)NULL);
/*HWND hbackground = CreateWindowEx(0,
L"STATIC",
NULL,
WS_CHILD | WS_VISIBLE | SS_BITMAP,
0,
0,
600,
400,
hWnd,
NULL,
NULL,
(LPVOID)NULL);
setImage(hbackground, L"test.bmp", 600, 400);*/
//SetWindowLong(hbackground, GWL_EXSTYLE, GetWindowLong(hbackground, GWL_EXSTYLE) | WS_EX_LAYERED);
//SetLayeredWindowAttributes(hbackground, 0, (255 * 50) / 100, LWA_ALPHA);
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code that uses hdc here...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
I'd like to set a specific window as the parent of a button, but I'm getting an expected behavior.
When the hMenu value on CreateWindow() is set, the button don't show up:
CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
(HMENU)1,
NULL, NULL);
But when I remove the hMenu parameter, the button does show up, but in a odd style:
CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
NULL,
NULL, NULL);
I'm not passing the HWND returned by the CreateWindow() of the main window into hwndParent of the button because they aren't called in that order.
The below code is a reduced version from my real one.
What am I missing?
Full code:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg = {0};
WNDCLASSW wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassW(&wc);
HWND
hwndMainWindow = CreateWindow(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 350,
NULL, NULL, hInstance, NULL);
HWND hButton = CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
NULL,
NULL, NULL);
SetParent(hButton, hwndMainWindow);
ShowWindow(hButton, SW_SHOWNORMAL);
UpdateWindow(hwndMainWindow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
You are not specifying the WS_CHILD style on the button. SetParent() does not set this style for you.
When you set the "parent" of a window that does not have WS_CHILD, you are actually setting its "owner" instead. Owner and Parent are not the same thing. Also see A window can have a parent or an owner but not both.
Your button does not appear in the main window because the button is not a child of the main window.
So, when creating the button, you need to include the WS_CHILD style. You should also include the WS_VISIBLE style instead of using ShowWindow() (unless you want to create the button hidden initially). And you should specify the parent window at the time of creation, instead of using SetParent().
You should also move your button creation into the WM_CREATE handler of your main window's WndProc().
Try this:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClass(&wc);
HWNDhwndMainWindow = CreateWindow(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 350,
NULL, NULL, hInstance, NULL);
ShowWindow(hwndMainWindow, SW_SHOWNORMAL);
UpdateWindow(hwndMainWindow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindow(L"Button",
L"Click me!",
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
20,
50,
60,
90,
hwnd,
(HMENU)1,
NULL, NULL);
break;
case WM_COMMAND:
if ((LOWORD(wParam) == 1) && (HIWORD(wParam) == BN_CLICKED)) {
MessageBox(hwnd, L"Yea, you clicked me!", L"Window", MB_OK);
return 0;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
When I call ShowCursor(0) (which by the way, does not take an HWND, this is weird), the cursor is hidden, but when I do a special action, for example resizing the window or drag-and-drop a file, the cursor corresponding to this action appears. I don't want to see the cursor whatever action the user is doing. If you wonder why, it's because I'd like to draw it with OpenGL.
I have a popup and layered window:
#define UNICODE
#include <windows.h>
#include <dwmapi.h>
LRESULT CALLBACK wnd_proc(HWND hWnd, UINT uMsg, WPARAM wp, LPARAM lp){
switch(uMsg){
case WM_CREATE: return 0;
case WM_NCHITTEST: return HTBOTTOM;
case WM_DESTROY: PostQuitMessage(0); return 0;
default: return DefWindowProc(hWnd, uMsg, wp, lp);
}
}
HDC hDC; HGLRC hRC;
int main(void){
WNDCLASSEX wcx = {};
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.lpfnWndProc = wnd_proc;
wcx.lpszClassName = L"Win32Class";
wcx.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wcx.hbrBackground = CreateSolidBrush(0x00000000);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClassEx(&wcx);
HWND hWnd = CreateWindowEx(WS_EX_ACCEPTFILES | WS_EX_LAYERED, wcx.lpszClassName,
L"Win32Window", WS_POPUP | WS_VISIBLE, 50, 50, 800, 400, NULL, NULL, NULL, NULL);
SetLayeredWindowAttributes(hWnd, RGB(200, 0, 200), 0, LWA_COLORKEY);
ShowCursor(0);
/*DWM_BLURBEHIND blur = {0};
blur.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
blur.fEnable = 1;
blur.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
DwmEnableBlurBehindWindow(hWnd, &blur);*/
MSG msg; while(GetMessage(&msg, NULL, 0, 0)){
DispatchMessage(&msg);
}
}
This is a truncated part of my test file. OpenGL is not included, but I just need to know how to delete the cursor.
If you compile and execute it, you can see that when your cursor is on the window, it is not visible, but when you resize the window the cursor appears, same as when you drag-and-drop a file.
there can be compile and link but show nothing to me but process.why?
i have download another Similar mine but this show me the window. i am confused.
#include<windows.h>
#include<stdio.h>
LRESULT CALLBACK WinSunProc(//可以通过MSDN查看回调函数的声明方式
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
){
WNDCLASS wndcls;//设计一个窗口类
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//黑色的刷子
wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);
wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);//窗口上面是应用程序的图标
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = WinSunProc;/窗口过程函数。回调函数
wndcls.lpszClassName = "First MFC";//类名
wndcls.lpszMenuName = NULL; //没有菜单
wndcls.style = CS_HREDRAW | CS_VREDRAW;//CS:类的样式---水平重绘、垂直重绘
RegisterClass(&wndcls);//注册窗口
HWND hwnd;//创建窗口
hwnd = CreateWindow("MFC", "JLU", WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOWNORMAL);//显示窗口
UpdateWindow(hwnd);
MSG msg;//消息循环机制
while (GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinSunProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
HDC hDC; //Device Context的句柄
switch (uMsg) //针对不同消息处理过程
{
case WM_PAINT: //窗口重绘时,触发的消息
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd, &ps); //BeginPaint/EndPaint只能用在WM_PAINT消息中
TextOut(hDC, 50, 50, "This is first MFC Program!", strlen("This is first MFC Program!"));
EndPaint(hwnd, &ps);
break;
case WM_CHAR: //按下键盘字母键响应消息
char cArry[20];
memset(cArry, 0, 20);
sprintf(cArry, "char is %d", wParam);
MessageBox(hwnd, cArry, "WM_CHAR", MB_OKCANCEL);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd, "LeftMouse Click", "WM_LBUTTONDOWN", MB_OKCANCEL);
hDC = GetDC(hwnd);
TextOut(hDC, 50, 100, "MFC Program!", strlen("MFC Program!"));
ReleaseDC(hwnd, hDC);
break;
case WM_CLOSE:
if (IDOK == MessageBox(hwnd, "是否真的要退出?", "提示", MB_OKCANCEL))
{
DestroyWindow(hwnd); //销毁窗口,同时发送WM_DESTROY消息
}
break;
case WM_DESTROY:
PostQuitMessage(0); //发送WM_QUIT消息
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam); //对待不关心的消息,采用默认方式处理
}
return 0;
}
i post the WINMAIN and CALLBACK function i cant found any error. please hellp me fix this.
First of all it is not an MFC application. It is just a very simple Win32 application written in C.
As far as I can tell your WindowProc function is WinQinProc(), but for some reason you do register your window class with WinSunProc. That's your first problem. The other problem is the name of your Window class (WNDCLASS). Please note that you should also use the same Window Class name registered in CreateWindow() call.
Here is the fixed version of your application (include "tchar.h" to make app UNICODE aware):
LRESULT CALLBACK WinSunProc(//可以通过MSDN查看回调函数的声明方式
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
WNDCLASS wndcls;//设计一个窗口类
wndcls.cbClsExtra = 0;
wndcls.cbWndExtra = 0;
wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//黑色的刷子
wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);
wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);//窗口上面是应用程序的图标
wndcls.hInstance = hInstance;
wndcls.lpfnWndProc = WinSunProc;
wndcls.lpszClassName = _T("MyClassName");//类名
wndcls.lpszMenuName = NULL; //没有菜单
wndcls.style = CS_HREDRAW | CS_VREDRAW;//CS:类的样式---水平重绘、垂直重绘
RegisterClass(&wndcls);//注册窗口
HWND hwnd;//创建窗口
hwnd = CreateWindow(_T("MyClassName"), _T("JLU"), WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOWNORMAL);//显示窗口
UpdateWindow(hwnd);
MSG msg;//消息循环机制
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinSunProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
HDC hDC; //Device Context的句柄
switch (uMsg) //针对不同消息处理过程
{
case WM_PAINT: //窗口重绘时,触发的消息
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd, &ps); //BeginPaint/EndPaint只能用在WM_PAINT消息中
TextOut(hDC, 50, 50, _T("This is first Win32 Program!"), _tcslen(_T("This is first Win32 Program!")));
EndPaint(hwnd, &ps);
break;
case WM_CHAR: //按下键盘字母键响应消息
char cArry[20];
memset(cArry, 0, 20);
// sprintf(cArry, "char is %d", wParam);
// MessageBox(hwnd, cArry, "WM_CHAR", MB_OKCANCEL);
break;
case WM_LBUTTONDOWN:
// MessageBox(hwnd, "LeftMouse Click", "WM_LBUTTONDOWN", MB_OKCANCEL);
hDC = GetDC(hwnd);
TextOut(hDC, 50, 100, _T("Win32 Program!"), _tcslen(_T("Win32 Program!")));
ReleaseDC(hwnd, hDC);
break;
case WM_CLOSE:
if (IDOK == MessageBox(hwnd, _T("是否真的要退出?"), _T("提示"), MB_OKCANCEL))
{
DestroyWindow(hwnd); //销毁窗口,同时发送WM_DESTROY消息
}
break;
case WM_DESTROY:
PostQuitMessage(0); //发送WM_QUIT消息
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam); //对待不关心的消息,采用默认方式处理
}
return 0;
}
I'm trying to create simple windows app uisng WinAPi.
Here is the code:
#include "stdafx.h"
#include "APIup.h"
#define MAX_LOADSTRING 100
HWND hWnd,cw13;
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
ATOM Register(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WndProc_dla13(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_APIUP, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
Register(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_APIUP));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APIUP));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_APIUP);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
ATOM Register(HINSTANCE hInstance)
{
WNDCLASSEX cw13class;
cw13class.cbSize = sizeof(WNDCLASSEX);
cw13class.style = CS_HREDRAW | CS_VREDRAW;
cw13class.lpfnWndProc = WndProc_dla13;
cw13class.cbClsExtra = 0;
cw13class.cbWndExtra = 0;
cw13class.hInstance = hInstance;
cw13class.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APIUP));
cw13class.hCursor = LoadCursor(NULL, IDC_ARROW);
cw13class.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
cw13class.lpszMenuName = NULL;
cw13class.lpszClassName = L"13class";
cw13class.hIconSm = LoadIcon(cw13class.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&cw13class);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 100, 100, NULL, NULL, hInstance, NULL);
cw13=CreateWindow(L"13class",L"Ćwiczenie 13",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,300,300,NULL,NULL,hInst,NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case ID_32771:
ShowWindow(cw13, 1);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK WndProc_dla13 (HWND hWnd, UINT msg/*message*/, WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindowW(L"button", L"Beep",
WS_VISIBLE | WS_CHILD ,
20, 50, 80, 25,
cw13, (HMENU) 1, hInst, NULL);
CreateWindowW(L"button", L"Quit",
WS_VISIBLE | WS_CHILD ,
120, 50, 80, 25,
cw13, (HMENU) 2, NULL, NULL);
break;
case WM_COMMAND:
if (LOWORD(wParam) == 1) {
Beep(40, 50);
}
if (LOWORD(wParam) == 2) {
PostQuitMessage(0);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
And the problem is that: when i create window 'cw13' it is created and displayed, but push buttons are not.I created two separate WndProc functions. Other messages are executed correctly( like WM_QUIT), only CreateWindowW under WM_CREATE,witch should create and show Push buttons aren't. Where is the problem?
When processing the WM_CREATE message, your call to CreateWindow(L"13class") is still running. Your cw13 variable has not been assigned yet, so you are assigning an invalid HWND as the parent of your buttons. That is why they do not appear. Use the hwnd parameter of WndProc_dla13() instead as the parent. That will be the same HWND that gets assigned to the cw13 variable once CreateWindow(L"13class") exits.