本文主要是在一个主窗口下创建一个子窗口。主窗口有一个菜单,菜单下只有设置一个选项,点击设置选项,弹出设置界面,点击设置界面关闭则关闭。我在开发的时候遇到两个问题,第一就是一点设置关闭就整个应用都关了,原来是destroy消息共用了。然后第二个是点击关闭后,设置界面再也显示不出来了,原来是close消息也要分拣。

   菜单志愿为IDR_MENU,设置ID选项为ID_SETTING。

   文件如下:

   Main.cpp   

#include "resource.h"
#include<tchar.h>
#include<stdio.h>
#include<windows.h>
#include "SettingMgr.h"
#define ClassName _T("sunxin2006")
HINSTANCE g_hInstance = 0;
LRESULT CALLBACK WinSunProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{
    WNDCLASS wndcls;
    wndcls.cbClsExtra = 0;
    wndcls.cbWndExtra = 0;
    wndcls.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wndcls.hCursor = LoadCursor(NULL,IDC_ARROW);
    wndcls.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wndcls.hInstance = hInstance;
    wndcls.lpfnWndProc = WinSunProc;
    wndcls.lpszClassName = _T("sunxin2006");
    wndcls.lpszMenuName = NULL;
    wndcls.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&wndcls);
    g_hInstance = hInstance;
    HWND hwnd = CreateWindow(ClassName,_T("helloworld"),WS_OVERLAPPEDWINDOW,
        0,0,600,400,NULL,LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MENU)),hInstance,NULL);
    ShowWindow(hwnd,SW_SHOW);
    UpdateWindow(hwnd);

    MSG msg;
    while(GetMessage(&msg,NULL,0,0)>0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
void OnCreate(HWND hwnd,WPARAM wParam,LPARAM lParam)
{
    int scrWidth,scrHeight;
    RECT rect;
    //获得屏幕尺寸
    scrWidth = GetSystemMetrics(SM_CXSCREEN);
    scrHeight = GetSystemMetrics(SM_CYSCREEN);
    //取得窗口尺寸
    GetWindowRect(hwnd,&rect);
    //重新设置rect里的值
    rect.left = (scrWidth-rect.right)/2;
    rect.top = (scrHeight-rect.bottom)/2;
    //移动窗口到指定的位置
    SetWindowPos(hwnd,HWND_TOP,rect.left,rect.top,rect.right,rect.bottom,SWP_SHOWWINDOW);
}

void OnComand(HWND hwnd,WPARAM wParam,LPARAM lParam)
{
    WORD uID = LOWORD(wParam);
    switch(uID)
    {
    case ID_SETTING:
        {
            if(SettingMgr::GetIntance()->m_SettingWnd)
            {
                ShowWindow(SettingMgr::GetIntance()->m_SettingWnd,SW_SHOW);
            }
            else
            {
                SettingMgr::GetIntance()->m_SettingWnd = 
                    CreateWindow(ClassName, "子窗口",  
                        WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE|WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, 400, 200,  
                          hwnd, NULL, g_hInstance, NULL);  
                ShowWindow(SettingMgr::GetIntance()->m_SettingWnd,SW_SHOW);
            }
        }
        break;
    }
}

VOID OnPaint(HWND hwnd,WPARAM wParam,LPARAM lParam)
{
    PAINTSTRUCT     ps; 
    RECT rtClient;
    GetClientRect(hwnd,&rtClient);
    HDC hdc = BeginPaint(hwnd, &ps);  
    HDC hMemDC = CreateCompatibleDC(hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rtClient.right - rtClient.left, rtClient.bottom - rtClient.top);//rt为RECT变量;
    SelectObject(hMemDC, hBitmap);
    FillRect(hMemDC, &rtClient,WHITE_BRUSH);
    char strText[100];
    if(hwnd == SettingMgr::GetIntance()->m_SettingWnd)
    {
        strcpy(strText,_T("我是子窗口!!!"));
    }
    else
    {
        strcpy(strText,_T("我是父窗口!!!"));
    }
    RECT rt={10,10,100,100};
    DrawText(hMemDC,strText,strlen(strText),&rt,DT_LEFT|DT_TOP);
    BitBlt(hdc, 0, 0,rtClient.right - rtClient.left, rtClient.bottom - rtClient.top, 
        hMemDC, 0, 0, SRCCOPY);
    DeleteDC(hMemDC);
    DeleteObject(hBitmap);
    ReleaseDC(hwnd,hdc);
}
LRESULT CALLBACK WinSunProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_CREATE:
        OnCreate(hwnd,wParam,lParam);
        break;
    case WM_COMMAND:
        OnComand(hwnd,wParam,lParam);
        break;
    case WM_PAINT:
        OnPaint(hwnd,wParam,lParam);
        break;
    case WM_CLOSE:
        if(hwnd == SettingMgr::GetIntance()->m_SettingWnd)
        {
            ShowWindow(SettingMgr::GetIntance()->m_SettingWnd,SW_HIDE);
        }
        else
        {
            DefWindowProc(hwnd,uMsg,wParam,lParam);
        }
        break;
    case WM_DESTROY:
        if(hwnd == SettingMgr::GetIntance()->m_SettingWnd)
        {
            
        }
        else
        {
            PostQuitMessage(0);
        }
        
        break;
    default:
        return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }
    return 0;
}
View Code

SettingMgr.h

#pragma once
#include<Windows.h>
class SettingMgr
{
protected:
    static SettingMgr* _Intance;
public:
    HWND m_SettingWnd;
public:
    SettingMgr(void);
    ~SettingMgr(void);
    static SettingMgr* GetIntance();
};
View Code

SettingMgr.cpp

#include "SettingMgr.h"
SettingMgr* SettingMgr::_Intance = new SettingMgr();
SettingMgr::SettingMgr(void):m_SettingWnd(NULL)
{
}

SettingMgr::~SettingMgr(void)
{

}

SettingMgr* SettingMgr::GetIntance()
{
    return _Intance;
}
View Code

由于例子很简单,所以用没用SettingMgr类效果不明显,如果结果比较麻烦,最好使用管理类。

注:修正一下错误,释放BeginPaint,需要调用EndPaint(hwnd,&ps),而不是ReleaseDC,失误了。。。抱歉。。。。

 

2、第二种方法,比较简单。创建时可以用不同的窗口类,注册时写一个另外的窗口函数。