2

我试图创建一个函数,该函数createscalingwindow调用CreateWindowEx并将使用的 HWND 的地址写入CreateWindowEx向量,然后是它的初始大小和位置值。

我调用的另一个函数scalewindowsize应该采用两个给定的窗口并用另一个窗口缩放一个窗口的大小,但目前我什至无法匹配某些 HWND 的地址,因为在某些条件下传递给的 HWND 的地址scalewindowsize将完全与初始化时的地址不同。这只发生在我scalewindowsize从窗口过程调用时,在窗口过程的参数中使用与在参数 for 中使用的 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;
  }
}

如果我运行这个程序,单击主机游戏,返回主窗口并稍微调整它的大小(在 mainrpoc 中设置 case WM_SIZE:)然后退出程序,我会按时间顺序收到以下消息框:

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++ 中的本地变量的方法是在变量之前添加 :: 之外,我还想添加。

4

2 回答 2

4

在这两个窗口过程中,您都将参数 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;
于 2013-01-05T00:25:03.623 回答
1

虽然 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 
        {
            ...
        }
    }
}

这应该可以解决您的问题。

于 2013-01-05T00:48:24.630 回答