I'm creating a window that's supposed to contain buttons.
When I create the first window (the container) I use a WNDCLASS to specify a WindowProc callback function to lpfnWndProc and it works as intended. When I do it the second time with a window, specifying a callback used to detect when the button is clicked, it doesn't work; the CreateWindowEx call there returns NULL (comment below shows where).
When I don't create WNDCLAS wB below and specify some other valid lpClassName to CreateWindowEx instead, such as Button it works fine.
code used
#pragma comment(linker, "/entry:wWinMainCRTStartup")
#include <windows.h>
#include <iostream>
HWND button;
LRESULT CALLBACK ButtonWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine,
int nCmdShow) {
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"textedit";
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(
0, wc.lpszClassName, L"textedit", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 340, 240, NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
return 0;
}
HWND hWndEdit = CreateWindowEx(WS_EX_CONTROLPARENT, L"Edit", L"id here",
WS_BORDER | WS_CHILD | WS_VISIBLE, 94, 20, 140,
40, hwnd, NULL, NULL, NULL);
// if I leave wcB unused/remove it and
// specify L"Button" as the lpClassName to CreateWindowEx below, the button displays
WNDCLASS wcB = {};
wcB.lpfnWndProc = ButtonWindowProc;
wcB.hInstance = hInstance;
wcB.lpszClassName = L"modify";
RegisterClass(&wcB);
ShowWindow(hwnd, nCmdShow);
// doing the exact same thing I did when creating the first window
// but it fails to create the window
HWND hButton =
CreateWindowEx(0L, L"modify", L"modify", BS_FLAT | WS_VISIBLE | WS_CHILD,
94, 70, 140, 50, hwnd, NULL, hInstance, NULL);
ShowWindow(hButton, nCmdShow);
// here hButton is NULL <----------------------
if (hButton == NULL) {
return 0;
}
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK ButtonWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case BN_CLICKED:
std::cout << "clicked";
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
return 0;
}
return 0;
return DefWindowProc(hwnd, uMsg, wParam, lParam);
};
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
GetLastError() returns 1400, but I don't understand how the handle hwnd could possible be invalid because as I mentioned before, when I just change the lpClassName I pass to CreateWindowEx, it works without errors.
I would appreciate any help in finding out why the window (the HWND of which is hButton) does not initiate, and possible workarounds.
The solution to the problem in the title was solved by the comment by Igor Tandetnik:
After fixing that, the window was created but was invisible. To fix that I used
FillRectwith a valid brush handleTo detect left mouse button clicks you need to check for the
WM_LBUTTONDOWNmessage.