Установить HWND на CreateWindow, похоже, не удается
Я из C# и очень новичок в этом, поэтому, пожалуйста, потерпите меня.
у меня есть MainWindow
класс, который имеет некоторые частные HWND
переменные. Один для самого окна и один для каждого элемента управления. Я предполагаю, что мне нужно следить за ними, или это облегчит ситуацию позже?
Во всяком случае, у меня есть:
class GUIMain
{
private:
HINSTANCE hInstance;
HWND hWnd; // The windows itself
HWND cmdGenerate, cmdQuit; // 2 buttons
У меня есть частный метод под названием initialise(HWND hWnd)
который называется на WM_CREATE
и он добавляет все элементы управления в окно:
void MainWindow::initialise(HWND hWnd)
{
this->hWnd = hWnd;
cmdGenerate = CreateWindow(TEXT("BUTTON"), TEXT("&Generate..."),
WS_VISIBLE | WS_CHILD,
6, 6, 150, 25,
hWnd, (HMENU)1, 0, 0);
cmdQuit = CreateWindow(TEXT("BUTTON"), TEXT("&Quit"),
WS_VISIBLE | WS_CHILD,
6, 37, 150, 25,
hWnd, (HMENU)2, 0, 0);
}
однако это, кажется, не помещает кнопки в окно. На самом деле, когда я отлаживаю, я вижу, что даже первая строка не проходит. Что странно, что когда я изменяю это на это:
void MainWindow::initialise(HWND hWnd)
{
//this->hWnd = hWnd;
/*cmdGenerate = */CreateWindow(TEXT("BUTTON"), TEXT("&Generate..."),
WS_VISIBLE | WS_CHILD,
6, 6, 150, 25,
hWnd, (HMENU)1, 0, 0);
/*cmdQuit = */CreateWindow(TEXT("BUTTON"), TEXT("&Quit"),
WS_VISIBLE | WS_CHILD,
6, 37, 150, 25,
hWnd, (HMENU)2, 0, 0);
}
кажется, работает нормально.
Логика, казалось бы, предполагает, что назначение частного HWND
Переменные значение CreateWindow
возврат функции вызывает проблемы, но я делал это раньше и не было проблемы?
Единственная разница между моим предыдущим кодом и этим кодом заключается в том, что я сейчас использую классы, тогда как раньше (пока я учился) у меня просто было все в WinMain
а также WndProc
,
WinMain: http://pastebin.com/j54vW9gc
Заголовочный файл: http://pastebin.com/cUs4vVJ6
Файл CPP: http://pastebin.com/B5KUXTvx
1 ответ
Добро пожаловать в мир win32, который не был разработан для C++. Это хорошая первая попытка. Я переделывал классы, пытаясь создать универсальную структуру сотни раз, прежде чем сказать, что это не стоит больше времени.
Ваш WinMain() также будет полезен, но большая проблема, которую я вижу, это ваш звонок CreateWindowEx()
, Последний параметр, который вы отправляете, равен 0. Чем при последующем получении SetWindowLong(hWnd, GWL_USERDATA, (long) ((LPCREATESTRUCT)lParam)->lpCreateParams);
Вы говорите, что это указатель на класс. Вы хотели иметь:
hWnd = CreateWindowEx(0, TEXT("AS2MainWindow"),
TEXT("AS2"),
WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT,
824, 350,
0, 0,
hInstance, this);
Ищу другие проблемы. Посмотрите, поможет ли это. Если нет, может быть, ваш пост ваш главный ()
Добавлено: CreateWindowEx
HWND WINAPI CreateWindowEx(
__in DWORD dwExStyle,
__in_opt LPCTSTR lpClassName,
__in_opt LPCTSTR lpWindowName,
__in DWORD dwStyle,
__in int x,
__in int y,
__in int nWidth,
__in int nHeight,
__in_opt HWND hWndParent,
__in_opt HMENU hMenu,
__in_opt HINSTANCE hInstance,
__in_opt LPVOID lpParam
);
Последний параметр lpParam
не является обязательным. Поэтому, когда вы установили его на 0, это не повредило ничего. Но так вы "отправляете" что-то WM_NCCREATE
или же WM_CREATE
, Это может быть любой LPVOID. В C вы можете отправить указатель на структуру или что угодно. В этом случае вы хотите отправить ему указатель на объект, который находится около вашего окна.
Чтобы получить этот параметр в WM_NCCREATE или WM_CREATE, используйте следующий код:
(long) ((LPCREATESTRUCT)lParam)->lpCreateParams);
Это говорит, бросили lParam
к pointer
к CREATESTRUCT
, Чем получить lpCreateParams
от него. и бросить это к long
, Это немного отличается от того, как я написал этот сложный для понимания фрагмент кода. Если разбить его на несколько шагов, это выглядит проще. Дайте мне знать, если вам нужно дальнейшее объяснение здесь.
Просто, чтобы вы получили полную картину ниже, это определение CreateStruct. В нем больше, чем просто lpCreateParams. (который вы выбрали указателем на ваш класс).
typedef struct tagCREATESTRUCT {
LPVOID lpCreateParams;
HINSTANCE hInstance;
HMENU hMenu;
HWND hwndParent;
int cy;
int cx;
int y;
int x;
LONG style;
LPCTSTR lpszName;
LPCTSTR lpszClass;
DWORD dwExStyle;
} CREATESTRUCT, *LPCREATESTRUCT;
После понимания всего этого. Проверьте ATL Thunking. Это путь, если вы хотите, чтобы весь ваш код был внутри классов. Я считаю, что лучше избегать КАЖДОЙ части кода, находящейся в классе, когда это не обязательно. Зависит от программы, которую я пишу.