简体   繁体   English

Win32:将lParam传递给CreateWindow并跟踪打开的窗口

[英]Win32: Passing lParam to CreateWindow and keeping track of open windows

To start, here is the description from the document I was given. 首先,这是我给的文档的描述。 NOTE: all I had to do was change existing code to meet these requirements 注意:我要做的就是更改现有代码以满足这些要求

Change the code to create 4 windows organized as shown in the demo. 更改代码以创建4个窗口,如演示中所示。 When the user closes a window, if there are other windows still open it does NOT kill the program. 当用户关闭一个窗口时,如果还有其他窗口仍在打开,则不会终止该程序。 The user must close ALL of them to stop program, 用户必须关闭所有程序才能停止程序,

You will need to keep track of the number of windows opened (and subtract when they are closed). 您将需要跟踪打开的窗口数(并在关闭窗口时减去)。 NO GLOBALS ALLOWED. 不允许全球。 NO STATICS ALLOWED. 暂无统计信息。

In addition your program must initialize the count using the lParam and CREATESTRUCT. 另外,您的程序必须使用lParam和CREATESTRUCT初始化计数。

Possible functions and structs:

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

Ok now, here is what I ended with. 好了,这就是我的结局。 I could open the 4 required windows, and had it so closing one window (sending the WM_DESTROY Message) did not end the entire program. 我可以打开4个必需的窗口,然后关闭一个窗口(发送WM_DESTROY消息)并没有结束整个程序。 What I am confused about is the passing of an lParam and using the CREATESTRUCT. 我感到困惑的是lParam的通过并使用了CREATESTRUCT。

Here is my wndproc.c: 这是我的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);

I'm trying to get the variable, which I pass as the lParam of the first window that is created, to be set as the Class Extra. 我正在尝试获取该变量,并将其作为创建的第一个窗口的lParam传递给它,并将其设置为Class Extra。 Does that make sense? 那有意义吗? Here is my main.c: 这是我的main.c:

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCMLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("HelloApplication"); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCMLine,int iCmdShow){静态TCHAR szAppName [] = TEXT(“ HelloApplication”); HWND hwnd; HWND hwnd; MSG msg; 味精味精; WNDCLASS wndclass; WNDCLASS wndclass; LONG* count; 长*计数;

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);

Any help would be appreciated; 任何帮助,将不胜感激; I've already been quizzed on this info in my class and did not understand it. 我已经在课堂上被问到了这个信息,却听不懂。 I'm posting this question for my own understanding only. 我发布此问题仅出于我自己的理解。

Thanks. 谢谢。

As you have to count the number of windows (instances) of the same window class, the counter needed can be seen as a static data member of the window class. 由于您必须计算同一窗口类的窗口(实例)数,因此所需的计数器可以视为窗口类的静态数据成员。

So the goal is to add some extra data (here an integer counter) to the window class. 因此,目标是向窗口类添加一些额外的数据(此处为整数计数器)。 To do so, one needs to tell windows to allocate this extra data. 为此,需要告诉Windows分配这些额外的数据。 This can be achieved by passing the right values to RegisterClass() . 这可以通过将正确的值传递给RegisterClass()来实现。 For the counter needed, set the member cbClsExtra of the structure of type WNDCLASS , which's reference is passed to the RegisterClass() , to the size of the integer counter. 对于所需的计数器,将WNDCLASS类型的结构的成员cbClsExtra设置为整数计数器的大小,该结构的引用将传递给RegisterClass()

To access the windows class' static data (and with it the integer counter) in the message dispatcher's callback method use GetClassLongPtr() . 要在消息分派器的回调方法中访问Windows类的静态数据(以及整数计数器),请使用GetClassLongPtr()

As I assume this is homework I leave the rest of the game as an exercise ... ;-) 因为我认为这是家庭作业,所以我将游戏的其余部分作为练习... ;-)

SetClassLongPtr - this function operates on the memory that is associated with the class of your window. SetClassLongPtr此函数对与窗口的类关联的内存进行操作。 This is essentially a static variable. 这本质上是一个静态变量。 In fact you have simple static counter of opened windows. 实际上,您具有打开的窗口的简单静态计数器。 It is just hidden under a smoke screen. 它只是隐藏在烟幕下。

Technically, from the point of C/C++, your counter is not static/global variable . 从技术上讲,从C / C ++的角度来看,您的计数器不是static/global variable But from the conceptual stand point - it is. 但是从概念的角度来看-是的。

lParam and CREATESTRUCT are non important details here. lParam和CREATESTRUCT在这里不是重要的细节。

The wrongness, the glasses they do nothing! 错了,眼镜他们什么也没做!

  • You can't pass an auto variable to CreateWindowEx , and expect the address of that variable (rather than the value that you're actually passing) to come through 您不能将自动变量传递给CreateWindowEx ,并且期望该变量的地址 (而不是您实际传递的值)通过
  • You can't assign a value to an auto variable ( int number = GetClassLongPtr(hwnd, 0); ), make changes to that variable, and expect them to be persistent. 您不能为自动变量分配一个值( int number = GetClassLongPtr(hwnd,0); ),对该变量进行更改,并期望它们是持久的。

In short: 简而言之:

  • Pass a pointer to CreateWindowEx , not a value 将指针传递给CreateWindowEx ,而不是值
  • Dereference that pointer when you want to make changes to the value stored therein 当您要更改其中存储的值时,请取消引用该指针

You may need to refresh your knowledge on pointers . 您可能需要刷新有关指针的知识。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM