C++ C+中的子窗口问题+;

C++ C+中的子窗口问题+;,c++,winapi,childwindow,C++,Winapi,Childwindow,每当我关闭子窗口时,我的程序就会出现问题,主窗口也会退出 我是这个节目的新手 正确的代码: /** @file MainWindow.cpp @author Andro Bondoc @date 2011-02-11 */ /** @file MainWindow.cpp @author Andro Bondoc @date 2011-02-11 */ #include "tray.h" #define WM_USER_SHELLICON WM_USE

每当我关闭子窗口时,我的程序就会出现问题,主窗口也会退出

我是这个节目的新手

正确的代码:

 /**
    @file MainWindow.cpp
    @author Andro Bondoc
    @date 2011-02-11
 */

   /** @file MainWindow.cpp @author Andro Bondoc @date 2011-02-11 */

#include "tray.h"



#define WM_USER_SHELLICON WM_USER + 1 

HWND hWnd, Button, LoadNew, TextBox;
HINSTANCE hInst;
HICON hMainIcon;
HMENU hPopMenu;
NOTIFYICONDATA structNID;

long PASCAL WndProcParent(HWND,UINT,UINT,LONG);
long PASCAL WndProcChild(HWND,UINT,UINT,LONG);


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{

    MSG msg;
    WNDCLASS wc, ws;

    hInst = hInstance;
    if(!hPrevInstance)
    {
        wc.style = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc = WndProcParent;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON));//LoadIcon(NULL,IDI_APPLICATION);
        wc.hCursor = LoadCursor(NULL,IDC_ARROW);
        wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
        wc.lpszMenuName = NULL;
        wc.lpszClassName = "Data Retriever Parent";
        RegisterClass(&wc);

        ws.style = CS_HREDRAW | CS_VREDRAW;
        ws.lpfnWndProc = WndProcChild;
        ws.cbClsExtra = 0;
        ws.cbWndExtra = 0;
        ws.hInstance = hInstance;
        ws.hIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON));//LoadIcon(NULL,IDI_APPLICATION);
        ws.hCursor = LoadCursor(NULL,IDC_ARROW);
        ws.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
        ws.lpszMenuName = NULL;
        ws.lpszClassName = "Data Retriever Child";
        RegisterClass(&ws);
    }

            hWnd = CreateWindowEx(0, wc.lpszClassName, "Data Retriever",
                       WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       NULL, NULL, hInstance, NULL);

            LoadNew = CreateWindowEx(0, ws.lpszClassName, "Help Program",
                       WS_BORDER | WS_CAPTION | WS_CHILD,
                       120,
                       80,
                       500,
                       300,
                       hWnd, NULL, hInstance, NULL);




    hMainIcon = LoadIcon(hInstance,(LPCTSTR)MAKEINTRESOURCE(IDI_TRAYICON)); 


    structNID.cbSize = sizeof(NOTIFYICONDATA);
    structNID.hWnd = (HWND) hWnd; 
    structNID.uID = IDI_TRAYICON; 
    structNID.uFlags = NIF_ICON | NIF_MESSAGE; 
    structNID.hIcon = hMainIcon; 
    structNID.uCallbackMessage = WM_USER_SHELLICON; 


    Shell_NotifyIcon(NIM_ADD, &structNID); 

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



long FAR PASCAL WndProcParent(HWND hwnd,UINT message,UINT wParam,long lParam)
{
   HDC hdc = NULL;
   POINT lpClickPoint;
   char buff[100] = "";

        switch(message){
                case WM_CREATE:

                Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Close",
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 680,480, 80, 30, hwnd, (HMENU)ID_CLOSE,
                GetModuleHandle(NULL), NULL);

                Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Help",
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 680,450, 80, 30, hwnd, (HMENU)ID_HELPDAW,
                GetModuleHandle(NULL), NULL);

                break;


        /*case WM_DESTROY:

                PostQuitMessage(0);
                return 0;*/

        case WM_USER_SHELLICON: 

            switch(LOWORD(lParam)) 
            { 
                case WM_LBUTTONDBLCLK: 
                    ShowWindow(hwnd, SW_RESTORE);
                    break;

                case WM_RBUTTONDOWN: 
                    //get mouse cursor position x and y as lParam has the message itself 
                    GetCursorPos(&lpClickPoint);

                    //place the window/menu there if needed 

                    hPopMenu = CreatePopupMenu();
                    InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_OPEN,"&Open");
                    InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_HELPDAW,"&Help");
                    InsertMenu(hPopMenu,0xFFFFFFFF,MF_BYPOSITION|MF_STRING,ID_CLOSE,"&Exit");

                        //workaround for microsoft bug, to hide menu w/o selecting
                    SetForegroundWindow(hWnd);
                    TrackPopupMenu(hPopMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_BOTTOMALIGN,lpClickPoint.x, lpClickPoint.y,0,hWnd,NULL);
                    SendMessage(hWnd,WM_NULL,0,0);

                    //MessageBox(NULL,"TEST rightclick","Testing ...",MB_OK); 

                    return TRUE; 
            }

            break; 

        case WM_COMMAND: 

            if(ID_CLOSE == LOWORD(wParam))
            {
                int iRes = MessageBox(NULL,"Do you want to Exit","Data Retriever",MB_YESNO|MB_ICONQUESTION);
                if(IDYES == iRes)
                {
                Shell_NotifyIcon(NIM_DELETE,&structNID);
                DestroyWindow(hWnd);
                PostQuitMessage(0);
                }

            }
            else if(ID_HELPDAW == LOWORD(wParam))
            {
                ShowWindow(LoadNew, SW_SHOW);
                //MessageBox(NULL, "Help","Data Retriever",MB_OK|MB_ICONQUESTION);                      
            }

            else if(ID_OPEN == LOWORD(wParam))
            {
                ShowWindow(hWnd, SW_NORMAL); 
            }
            break;

        case WM_CLOSE: 

                Shell_NotifyIcon(NIM_DELETE,&structNID);
                DestroyWindow(hWnd);
                PostQuitMessage(0);

            break;

        case WM_SYSCOMMAND: 

            if(SC_MINIMIZE == wParam) 
            { 
                ShowWindow(hWnd,SW_HIDE);
                return TRUE; 
            }
            break;

  }
return DefWindowProc(hwnd,message,wParam,lParam);
}

long FAR PASCAL WndProcChild(HWND hwnd,UINT message,UINT wParam,long lParam){
   HDC hdc = NULL;
   PAINTSTRUCT ps;
   char buff[100] = "";
   switch(message){
                case WM_CREATE:

                Button = CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", "Unload",
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20,20, 80, 30, hwnd, (HMENU)ID_MESSAGE,
                GetModuleHandle(NULL), NULL);


                break;


        case WM_COMMAND: 


            if(ID_RETURN == LOWORD(wParam))
            {
                ShowWindow(hWnd, SW_SHOW);
                ShowWindow(LoadNew,SW_HIDE);
                //MessageBox(NULL, "Help","Data Retriever",MB_OK|MB_ICONQUESTION);                      
            }


        case WM_CLOSE: 

            ShowWindow(hWnd, SW_SHOW);
            ShowWindow(LoadNew,SW_HIDE);
            break;

        case WM_PAINT:

            RECT rect;

            GetClientRect(LoadNew,&rect);
            hdc = BeginPaint(LoadNew,&ps);

            strcpy_s(buff,"TOP");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_TOP);
            strcpy_s(buff,"RIGHT");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_VCENTER|DT_RIGHT);
            strcpy_s(buff,"BOTTOM");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_BOTTOM);
            strcpy_s(buff,"LEFT");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
            strcpy_s(buff,"CENTER");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
            strcpy_s(buff,"BOTTOM-LEFT");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_BOTTOM|DT_LEFT);
            strcpy_s(buff,"BOTTOM-RIGHT");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_BOTTOM|DT_RIGHT);
            strcpy_s(buff,"TOP-LEFT");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_TOP|DT_LEFT);
            strcpy_s(buff,"TOP-RIGHT");
            DrawText(hdc,buff,strlen(buff), &rect,DT_SINGLELINE|DT_TOP|DT_RIGHT);

            EndPaint(LoadNew,&ps);
            break;
        }
return DefWindowProc(hwnd,message,wParam,lParam);
}

每个窗口都有相同的wndproc代码。对于WM_CLOSE,您需要销毁窗口(hWnd),其中hWnd是存储主窗口的全局窗口


因此,关闭子窗口会关闭主窗口,因为您告诉它关闭主窗口。

您修改的代码仍然对两个窗口使用相同的WndProc。您尝试使用相同的类名调用RegisterClass两次。在您更改名称之前,WNDPROC不会分离

ws.lpszClassName = "Data Retriever CHILD";

如果您已经检查了RegisterClass的返回值,那么这个问题就会更加明显——目前,第二个调用失败。这段代码还有其他问题(例如,子WndProc中的MessageBox调用确实令人讨厌),但这一更改应该足以让您朝着正确的方向前进。

您必须提供更多详细信息。源代码会很有帮助。另外,您使用的是哪种操作系统和框架?我假设您正在编写一个针对Win32 API的程序?请发布代码的相关部分。对于初学者,您可以在其中创建并关闭子窗口。最好是编辑原始问题以发布代码。注释不允许多行,或具有任何类型的语法突出显示。使用标签下面的编辑超链接。首先,你应该创建单独的WNDPROC-我怀疑主窗口的行为100%适用于子窗口,等等。一般来说,在子窗口的wnd proc中,不应该对父窗口进行任何操作。如果我要创建一个新的wndprocs,那么调用子窗口>,是否也一样?我创建了一个新的wndprocs,但出现了一个错误。这是错误:函数“long WndProc(HWND,UINT,UINT,long)”已具有body@Andro:给他们起不同的名字,例如
wndproccident
wndproccidel
。函数名并不重要,重要的是在
WNDCLASS
结构中设置
lpfnWndProc
的值,以指向相应的窗口过程注意,您需要注册两个窗口类,一个用于父窗口,还有一个是给孩子的。@Micheal-我分开了wndProcs,但它仍然从主窗口退出