Win32: передача lParam в CreateWindow и отслеживание открытых окон

Для начала, вот описание из документа, который мне дали.
ПРИМЕЧАНИЕ: все, что мне нужно было сделать, это изменить существующий код, чтобы соответствовать этим требованиям

Измените код, чтобы создать 4 окна, организованные, как показано в демонстрации.
Когда пользователь закрывает окно, если другие окна все еще открыты
это НЕ убивает программу. Пользователь должен закрыть ВСЕ из них, чтобы остановить программу,

Вам нужно будет отслеживать количество открытых окон (и вычитать
когда они закрыты). ГЛОБАЛЫ НЕ ДОПУСКАЮТСЯ. СТАТИКА НЕ ДОПУСКАЕТСЯ.

Кроме того, ваша программа должна инициализировать счет с использованием lParam и CREATESTRUCT.

Possible functions and structs:

SetWindowLong()
GetWindowLong()
SetClassLong()
GetClassLong()
CREATESTRUCT

Хорошо, вот что я закончил. Я мог открыть 4 требуемых окна, и при этом закрытие одного окна (отправка сообщения WM_DESTROY) не заканчивало всю программу. Что меня смущает, так это прохождение lParam и использование CREATESTRUCT.

Вот мой wndproc.c:

 LRESULT CALLBACK HelloWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
HDC     hdc;
PAINTSTRUCT ps;
RECT    rect;
int number = GetClassLongPtr(hwnd, 0);

switch (message){
case WM_CREATE:
if(number == 0){
SetClassLongPtr(hwnd, 0, (LONG)((CREATESTRUCT*)lParam)->lpCreateParams);
}
number++;
return 0;

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);

GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("Unique yet the same!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);

EndPaint(hwnd, &ps);
return 0;

case WM_DESTROY:
number--;
if(number == 0){
PostQuitMessage(0);
}
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);

Я пытаюсь получить переменную, которую я передаю как lParam первого созданного окна, для установки в качестве дополнительного класса. Имеет ли это смысл? Вот мой main.c:

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCMLine, int iCmdShow) {
статический TCHAR szAppName [] = TEXT («HelloApplication»);
HWND HWND;
MSG MSG;
WNDCLASS wndclass;
ДОЛГО * количество;

wndclass.style      = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = HelloWndProc;
wndclass.cbClsExtra = 5;
wndclass.cbWndExtra = 0;
wndclass.hInstance  = hInstance;
wndclass.hIcon      = LoadIcon (NULL, IDI_APPLICATION);
wndclass.hCursor    = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;if (!RegisterClass (&wndclass)){
MessageBox (NULL, TEXT ("This program requires Windows 95/98/NT"),
szAppName, MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(szAppName,
TEXT("Hello World for Windows"),
WS_OVERLAPPEDWINDOW,
100,
50,
400,
300,
NULL,
NULL,
hInstance,
count = 0);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

Любая помощь будет оценена; Я уже проверял эту информацию в своем классе и не понимал ее. Я публикую этот вопрос только для собственного понимания.

Благодарю.

0

Решение

Поскольку вы должны посчитать количество окон (экземпляров) одного и того же класса окон, необходимый счетчик можно рассматривать как статический элемент данных класса окна.

Таким образом, цель состоит в том, чтобы добавить некоторые дополнительные данные (здесь целочисленный счетчик) к классу окна. Для этого нужно указать окнам выделять эти дополнительные данные. Это может быть достигнуто путем передачи правильных значений RegisterClass(), Для счетчика необходимо установить член cbClsExtra структуры типа WNDCLASS, ссылка на которую передается RegisterClass(), до размера счетчика целых чисел.

Для доступа к статическим данным класса Windows (и вместе с ними счетчик целых чисел) в методе обратного вызова диспетчера сообщений используйте GetClassLongPtr(),

Поскольку я предполагаю, что это домашнее задание, я оставляю остальную часть игры в качестве упражнения … 😉

1

Другие решения

SetClassLongPtr — эта функция работает с памятью, которая связана с классом вашего окна. По сути, это статическая переменная. На самом деле у вас есть простой статический счетчик открытых окон. Он просто спрятан под дымовой завесой.

Технически, с точки зрения C / C ++, ваш счетчик не static/global variable, Но с концептуальной точки зрения — это так.

lParam и CREATESTRUCT не являются важными деталями здесь.

1

Неправильность, очки они ничего не делают!

  • Вы не можете передать автоматическую переменную CreateWindowExи ожидать адрес этой переменной (а не значение, которое вы фактически передаете), чтобы пройти через
  • Вы не можете присвоить значение автоматической переменной (int number = GetClassLongPtr (hwnd, 0);), внесите изменения в эту переменную и ожидайте, что они будут постоянными.

Короче:

  • Передать указатель на CreateWindowExне значение
  • Разыменуйте этот указатель, когда вы хотите внести изменения в значение, хранящееся в нем

Возможно, вам придется обновить свои знания о указатели.

1
По вопросам рекламы [email protected]