Win32子窗口的創建


   本文主要是在一個主窗口下創建一個子窗口。主窗口有一個菜單,菜單下只有設置一個選項,點擊設置選項,彈出設置界面,點擊設置界面關閉則關閉。我在開發的時候遇到兩個問題,第一就是一點設置關閉就整個應用都關了,原來是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、第二種方法,比較簡單。創建時可以用不同的窗口類,注冊時寫一個另外的窗口函數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM