c++ - C++中的子窗口问题

标签 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_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,您 DestroyWindow(hWnd),其中 hWnd 是存储主窗口的全局变量。

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

关于c++ - C++中的子窗口问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5000189/

相关文章:

winapi - 如何打开 "nul"文件?

c++ - 使用 glDrawArrays() 的绘制函数需要调用两次才能显示任何内容

delphi如何防止MDI子被最大化?

.net - 学习Win32开发GUI应用程序

c++ - C++ ifstream I/O?

c++ - 链接到 SFML dll 的程序无法启动,返回 0xC000007B 或缺少 __gxx_personality_v0

c++ - 获取二进制指令的内存地址

c# - 在 C# WinForms 中,如何摆脱 child 的控制栏?

c++ - 在 Windows API 上创建子窗口

c++ - 错误 C3861 : 'D3DCompileFromFile' : identifier not found