Установить HWND на CreateWindow, похоже, не удается - PullRequest
2 голосов
/ 07 ноября 2011

Я из 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 Ответ

6 голосов
/ 07 ноября 2011

Добро пожаловать в мир 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. Это путь, если вы хотите, чтобы весь ваш код был внутри классов. Я считаю, что лучше избегать КАЖДОГО куска кода, находящегося в классе, когда это не обязательно. Зависит от программы, которую я пишу.

...