Адрес HWND изменяется, когда используется для параметра внутри его windproc

Я пытался сделать функцию createscalingwindow что вызывает CreateWindowEx и записывает адрес HWND, используемого в CreateWindowEx к вектору, за которым следуют его начальный размер и значения положения.

Еще одна функция, которую я сделал, называется scalewindowsize предполагалось взять два заданных окна и масштабировать размер одного окна с другим, но в настоящий момент я не могу даже сопоставить адреса определенных HWND, потому что при определенных условиях адрес HWND передавался scalewindowsize будет полностью отличаться от адреса при инициализации. Это происходит только когда я звоню scalewindowsize из оконной процедуры, используя тот же HWND в параметре оконной процедуры, что и HWND, используемый в параметре для scalewindowsize, Ниже приведен соответствующий код:

#include <windows.h>
#include <stdio.h>
#include <winsock.h>
#include <vector>
#define ID_1 1000
#define ID_2 1001
#define ID_3 1002
HWND mainwin;
HWND lobbywin;
int zero = 0;
char MENU1;
std::vector<intptr_t> sizevalues;
LRESULT CALLBACK mainproc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK lobbyproc (HWND, UINT, WPARAM, LPARAM);
char mainclassname[] = "main";
char lobbyclassname[] = "lobby";

void createscalingwindow(HWND &cswpara0,DWORD cswpara1,const CHAR* cswpara2,
const CHAR* cswpara3,DWORD cswpara4,int cswpara5,int cswpara6,int cswpara7,
int cswpara8,HWND cswpara9,HMENU cswpara10,HINSTANCE cswpara11,LPVOID cswpara12)
{
cswpara0 = CreateWindowEx (cswpara1, cswpara2, cswpara3, cswpara4,cswpara5,
cswpara6,cswpara7,cswpara8,cswpara9,cswpara10,cswpara11,cswpara12);
char buffer[100];
sizevalues.push_back((intptr_t)&cswpara0);
snprintf (buffer, 20,"%d", sizevalues[zero]);
MessageBox (NULL, buffer, "initialized", NULL);
zero = (zero + 1);
return;
}

void scalewindowsize (HWND &ownerwin, const CHAR* tryz)
{
char buffer[100];
int checknumber = 0;
while (checknumber < sizevalues.size())
{
int compare = sizevalues[checknumber];
if (sizevalues[checknumber] == (intptr_t)&ownerwin)
{
snprintf (buffer, 100,"%d", (intptr_t)&ownerwin);
MessageBox (NULL, buffer, "value found", NULL);
break;
}
else
{
snprintf (buffer, 100,"%d", (intptr_t)&ownerwin);
MessageBox (NULL, buffer, tryz, NULL);
snprintf (buffer, 100,"%d", sizevalues[checknumber]);
checknumber = (checknumber + 1);
MessageBox (NULL, buffer, "fail currentcheck", NULL);
}
}
return;
}

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
LPSTR lpszArgument, int nCmdShow)
{
MSG messages;
WNDCLASSEX mainwinclass;
mainwinclass.hInstance = hThisInstance;
mainwinclass.lpszClassName = mainclassname;
mainwinclass.lpfnWndProc = mainproc;
mainwinclass.style = CS_DBLCLKS;
mainwinclass.cbSize = sizeof (WNDCLASSEX);
mainwinclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
mainwinclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
mainwinclass.hCursor = LoadCursor (NULL, IDC_ARROW);
mainwinclass.lpszMenuName = NULL;
mainwinclass.cbClsExtra = 0;
mainwinclass.cbWndExtra = 0;
mainwinclass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&mainwinclass))
return 0;

WNDCLASSEX lobbywinclass;
lobbywinclass.hInstance = hThisInstance;
lobbywinclass.lpszClassName = lobbyclassname;
lobbywinclass.lpfnWndProc = lobbyproc;
lobbywinclass.style = CS_DBLCLKS;
lobbywinclass.cbSize = sizeof (WNDCLASSEX);
lobbywinclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
lobbywinclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
lobbywinclass.hCursor = LoadCursor (NULL, IDC_ARROW);
lobbywinclass.lpszMenuName = NULL;
lobbywinclass.cbClsExtra = 0;
lobbywinclass.cbWndExtra = 0;
lobbywinclass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;if (!RegisterClassEx (&lobbywinclass))
return 0;
HMENU playmenu = CreateMenu();
HMENU playmenulist = CreatePopupMenu();
HMENU helpmenulist = CreatePopupMenu();
AppendMenu(playmenulist, MF_STRING, ID_1, "Join game");
AppendMenu(playmenulist, MF_STRING, ID_3, "Host game");
AppendMenu(playmenulist, MF_STRING, ID_2, "Quit");
InsertMenu(playmenu, 1, MF_POPUP|MF_BYPOSITION, (UINT_PTR)playmenulist, "Play");

createscalingwindow(mainwin, 0, mainclassname, "mainwindow",
WS_OVERLAPPED|WS_CAPTION|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, NULL, playmenu, hThisInstance, NULL);
ShowWindow (mainwin, nCmdShow);

createscalingwindow(lobbywin, 0, lobbyclassname, "Lobby", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 600, 425, NULL, NULL, hThisInstance, NULL);

while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}

LRESULT CALLBACK mainproc(HWND mainwin, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
scalewindowsize (mainwin, "mainwin");
scalewindowsize (lobbywin, "lobbywin");
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
}
switch (wParam)
{
case ID_3:
EnableWindow (mainwin, false);
ShowWindow (mainwin, false);
ShowWindow (lobbywin, true);
break;
default:
return DefWindowProc (mainwin, message, wParam, lParam);
break;
}
return 0;
}
LRESULT CALLBACK lobbyproc(HWND lobbywin, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
scalewindowsize (mainwin, "mainwin");
scalewindowsize (lobbywin, "lobbywin");
break;
}
break;
}
switch (wParam)
{
case SC_CLOSE:
{
EnableWindow (mainwin, true);
ShowWindow (mainwin, true);
ShowWindow (lobbywin, false);
EnableWindow (lobbywin, false);
break;
}
default:
return DefWindowProc (lobbywin, message, wParam, lParam);
break;
}
}

Если я запускаю эту программу, нажимаю на хост-игру, возвращаюсь к главному окну и немного изменяю его размер (за исключением случая WM_SIZE: в mainrpoc), затем выхожу из программы, я получаю следующие сообщения в хронологическом порядке:

1[title: Initialized |text: 4231184]
2[title: mainwin |text: 2292968]
3[title: fail currentcheck |text: 4231184]
4[title: lobbywin |text: 4231188]
5[title: fail currentcheck |text: 4231184]
6[title: initialized |text: 4231188] (no more boxes until I click on host game)
7[title: value found: |text: 4231184]
8[title: lobbywin |text: 2292676]
9[title: fail currentcheck |text: 4231184]
10[title: lobbywin |text: 2292676]
11[title: fail currentcheck |text: 4231188] (no more boxes until I go back to the mainwindow and resize it slightly)
12[title: mainwin |text: 2291164]
13[title: fail currentcheck |text: 4231184]
14[title: mainwin |text: 2291164]
15[title: fail currentcheck |text: 4231188]
16[title: lobbywin |text: 4231188]
17[title: fail currentcheck |text: 4231184]
18[title: value found |text: 4231188]

Я очень смущен сейчас, я надеюсь, что кто-то, читающий это, может объяснить мне, почему адрес меняется, заранее благодарю вас за то, что нашли время, чтобы прочитать мой вопрос.

ОБНОВЛЕНИЕ: для тех, кто читает это, я хотел бы добавить в дополнение к whoz craigs ответ, что способ вызова глобальной переменной вместо локальной в c ++ состоит в том, чтобы добавить :: перед переменной.

2

Решение

В обеих оконных процедурах вы отправляете параметр HWND в scalewindow; не глобальный. Таким образом, они разные адреса. Разрешение имен использует «ближайшую» переменную, которая в обоих случаях является параметром HWND, а не глобальным HWND, который вы пытаетесь использовать.

Пример:

LRESULT CALLBACK mainproc(HWND mainwin, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
scalewindowsize (mainwin, "mainwin");   // passes parameter mainwin by reference
scalewindowsize (lobbywin, "lobbywin"); // passes global lobbywin by reference
break;
}

Таким образом, ссылки будут иметь разное разрешение адресов. Другой пример:

LRESULT CALLBACK lobbyproc(HWND lobbywin, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
scalewindowsize (mainwin, "mainwin");   // passes global mainwin by reference
scalewindowsize (lobbywin, "lobbywin"); // passes parameter lobbywin by reference
break;
}
break;
4

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

Хотя WhozCraig уже ответил на вопрос, который вы задали, я объясню, как получить то, что вы действительно хотели. Все сводится к вашему решению сохранить адрес HWND быть неправильным решением. Просто сохраните HWND — он уже имеет размер указателя, поэтому вы не теряете места и не выполняете дорогостоящие операции копирования.

Ваш контейнер должен быть:

std::vector<HWND> sizevalues;

Измени свой createscalingwindow функция к этому (псевдокод):

void createscalingwindow( ... )
{
cswpara0 = CreateWindowEx( .... );
sizevalues.push_back(cswpara0);
...
}

И ваш scalewindowsize Функция должна быть изменена следующим образом (опять же, псевдокод, только с теми частями, которые требуют изменений):

void scalewindowsize(HWND ownerwin, ...)
{
char buffer[100];
int checknumber = 0;
while (checknumber < sizevalues.size())
{
if (sizevalues[checknumber] == ownerwin)
{
...
}
else
{
...
}
}
}

Это должно исправить ваши проблемы.

1

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