本例在SDK下使用API函数实现窗体的创建、销毁、显示和隐藏!
1、打开VC6,单击File/New菜单,选择Win32 Application ,建立工程名为WindowDemo的应用程序。
2、选择“A simple Win32 Application”
3、向工程中添加一个菜单资源,ID为IDR_MAIN,在菜单中添加一个子菜单“测试窗体1”,包含四个菜单项,
ID为:“ID_MI_WND1_CREATE”、“ID_MI_WND1_DESTROY”、“ID_MI_WND1_SHOW”、“ID_MI_WND1_HIDE” ,
文本为“创建”、“销毁”、“显示”、“隐藏”。
再为IDR_MAIN添加第二个子菜单“测试窗体2”,只是把“1”改为“2”
///
///MyWnd.h中
#define MY_WND_PROP_NAME _T("_My_Wnd_Prop_Name_")
#define MY_WND_CLASS_NAME _T("_My_Wnd_Class_Name_")
class CMyWnd
{
public:
CMyWnd();
virtual ~CMyWnd();
//创建窗体
HWND CreateEx(HINSTANCE hInst ,DWORD dwExstyle , LPCTSTR lpText ,DWORD dwStyle ,
LPRECT lprcWnd ,HWND hParent ,int nMenuID);
HWND CreateEX(DWORD dwStyle ,int x,int y , int nWidth ,int nHeight ,HWND hParent);
///销毁窗体
void Destroy();
///显示或隐藏窗体
BOOL Show(int nCmd);
///获取窗体句柄
HWND GetHwnd();
///可直接返回窗体句柄的操作符
operator HWND() const;
protected:
///处理前的派生类调用机会
virtual BOOL preprocessMsg(HWND hWnd ,UINT nMsg ,WPARAM wp ,LPARAM lp ,LRESULT *pResult);
//窗体创建消息
virtual LRESULT OnCreate(HWND hWnd);
///窗体销毁消息
virtual BOOL OnDestroy();
///处理命令按钮消息
virtual BOOL OnCommand(int nCmdID);
///绘制窗体
virtual BOOL OnPaint();
///绘制背景
virtual BOOL OnEraseBk(HDC hDC);
///timer消息
virtual BOOL OnTimer(int nID);
protected:
///检测类是否注册,如果没有注册则注册
BOOL CheckClass(LPCTSTR lpClassName);
///窗体过程
static LRESULT CALLBACK WndProc(HWND hWnd ,UINT nMsg ,WPARAM wp, LPARAM lp);
protected:
HWND m_hWnd;
HMENU m_hMenu;
HINSTANCE m_hInstance;
};
#endif // !defined(AFX_MYWND_H__6B084A95_8F56_430C_909F_6869193CD5AA__INCLUDED_)
// MyWnd.cpp: implementation of the CMyWnd class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyWnd.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMyWnd::CMyWnd():m_hWnd(NULL),m_hMenu(NULL),m_hInstance(NULL)
{
}
CMyWnd::~CMyWnd()
{
if(m_hWnd)
{
Destroy();
}
}
HWND CMyWnd::CreateEx(HINSTANCE hInst ,DWORD dwExStyle ,LPCTSTR lpText ,DWORD dwStyle ,
LPRECT lprcWnd ,HWND hParent ,int nMenuID)
{
///如果已经创建,返回,防止重复创建
if(m_hWnd)
{
return m_hWnd;
}
///hInst由WinMain传入
m_hInstance = hInst;
///计算窗体尺寸
int x,y,nWidth,nHeight;
if(lprcWnd == NULL)
{
x = y =nWidth = nHeight = CW_USEDEFAULT;
}
else
{
x = lprcWnd->left;
y = lprcWnd->top;
nWidth = lprcWnd->right - lprcWnd->left;
nHeight = lprcWnd->bottom - lprcWnd->top;
}
///如果有菜单,加载菜单,并作为窗体菜单
if(nMenuID > 0 )
m_hMenu = LoadMenu(m_hInstance ,MAKEINTRESOURCE(nMenuID));
///检测类名是否已经注册
CheckClass(MY_WND_CLASS_NAME);
///创建窗体
m_hWnd = CreateWindowEx(dwExStyle , MY_WND_CLASS_NAME ,lpText ,dwStyle ,x, y ,
nWidth ,nHeight ,hParent ,m_hMenu , m_hInstance ,this);
return m_hWnd;
}
HWND CMyWnd::CreateEX(DWORD dwStyle ,int x,int y , int nWidth ,int nHeight ,HWND hParent)
{
///创建窗体的重载函数
RECT rc = {x , y , x + nWidth , y + nHeight};
return CreateEx(NULL , 0 , _T("MyWnd") , dwStyle ,&rc ,hParent , 0);
}
void CMyWnd::Destroy()
{
///销毁窗体
if(m_hWnd)
{
DestroyWindow(m_hWnd);
m_hWnd = NULL;
}
}
BOOL CMyWnd::Show(int nCmd)
{
///显示或隐藏窗口
return ShowWindow(m_hWnd , nCmd);
}
HWND CMyWnd::GetHwnd()
{
//返回窗体句柄
return m_hWnd;
}
CMyWnd::operator HWND() const
{
return m_hWnd;
}
BOOL CMyWnd::preprocessMsg(HWND hWnd , UINT nMsg ,WPARAM wp ,LPARAM lp , LRESULT *pResult)
{
///返回所有消息处理前,会调用此函数
//返回TRUe代表继续由相应消息响应函数处理,否则不用再处理
///消息的返回值由pResult中返回
return TRUE;
}
LRESULT CMyWnd::OnCreate(HWND hWnd)
{
//WM_CREATE消息的响应函数
return 0;
}
BOOL CMyWnd::OnDestroy()
{
return true;
}
BOOL CMyWnd::OnCommand(int nCndID)
{
return true;
}
BOOL CMyWnd::OnPaint()
{
return true;
}
BOOL CMyWnd::OnEraseBk(HDC hDC)
{
return true;
}
BOOL CMyWnd::OnTimer(int nID)
{
return true;
}
BOOL CMyWnd::CheckClass(LPCTSTR lpClassName)
{
///检测类名,如果没有注册,则注册
WNDCLASS wc = {0};
if(!GetClassInfo(m_hInstance , lpClassName ,&wc))///GetClassInfo()函数用于检测一个类是否被注册
{
wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = lpClassName;
return RegisterClass(&wc);
}
return true;
}
LRESULT CALLBACK CMyWnd::WndProc(HWND hWnd , UINT nMsg , WPARAM wp ,LPARAM lp)
{
///消息处理的约定:
///1、派生类处理了某个消息处理函数后,无需再调用基类处理,调用基类意味着默认处理
///2、消息处理,除特殊消息外,返回TRUE代表要调用默认处理,否则不调用默认处理
LRESULT lResult = 0 ;
BOOL bCallDefault = true;
///取出和句柄相对应的类
CMyWnd *pWnd = (CMyWnd*)GetProp(hWnd ,MY_WND_PROP_NAME);////GetProp()函数的作用
if(pWnd == NULL)
{
if(nMsg != WM_CREATE)
{
return DefWindowProc(hWnd ,nMsg,wp , lp);
}
else
{
LPCREATESTRUCT pSt = (LPCREATESTRUCT)lp;
pWnd = (CMyWnd*)pSt->lpCreateParams;
SetProp(hWnd ,MY_WND_PROP_NAME ,pWnd);
}
}
if(!pWnd->preprocessMsg(hWnd ,nMsg ,wp ,lp ,&lResult))
return lResult;
///处理消息
switch(nMsg)
{
case WM_CREATE:
{
pWnd->m_hWnd = hWnd;
lResult = pWnd->OnCreate(hWnd);
bCallDefault = false;
break;
}
case WM_DESTROY:
bCallDefault = pWnd->OnDestroy();
break;
case WM_COMMAND:
bCallDefault = pWnd->OnCommand(LOWORD(wp));
break;
case WM_PAINT:
bCallDefault = pWnd->OnPaint();
break;
case WM_ERASEBKGND:
bCallDefault = pWnd->OnEraseBk((HDC)wp);////???????????
break;
case WM_CLOSE:
pWnd->Destroy();
bCallDefault = false;
break;
case WM_TIMER:
bCallDefault = pWnd->OnTimer((int)wp);
break;
default:
break;
}
///根据消息处理结果调用默认的处理过程,或者直接返回
if(bCallDefault)
return DefWindowProc(hWnd , nMsg , wp , lp);
else
return lResult;
}
再向工程中添加三个类“CMainWnd”、“CChildWnd1”、“CChildWnd2”,均继承自CMyWnd
// MainWnd.h: interface for the CMainWnd class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINWND_H__2910B9F6_DCDC_4E34_B367_DDDDDEB4F1AD__INCLUDED_)
#define AFX_MAINWND_H__2910B9F6_DCDC_4E34_B367_DDDDDEB4F1AD__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MyWnd.h"
#include "ChildWnd1.h"
#include "ChildWnd2.h"
class CMainWnd : public CMyWnd
{
public:
CMainWnd();
virtual ~CMainWnd();
protected:
BOOL OnCommand(int ncmdID);
BOOL OnDestroy();
private:
CChildWnd1 m_wndChild1;///测试窗体1
CChildWnd2 m_wndChild2;///测试窗体2
};
#endif // !defined(AFX_MAINWND_H__2910B9F6_DCDC_4E34_B367_DDDDDEB4F1AD__INCLUDED_)
// MyWnd.cpp: implementation of the CMyWnd class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyWnd.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMyWnd::CMyWnd():m_hWnd(NULL),m_hMenu(NULL),m_hInstance(NULL)
{
}
CMyWnd::~CMyWnd()
{
if(m_hWnd)
{
Destroy();
}
}
HWND CMyWnd::CreateEx(HINSTANCE hInst ,DWORD dwExStyle ,LPCTSTR lpText ,DWORD dwStyle ,
LPRECT lprcWnd ,HWND hParent ,int nMenuID)
{
///如果已经创建,返回,防止重复创建
if(m_hWnd)
{
return m_hWnd;
}
///hInst由WinMain传入
m_hInstance = hInst;
///计算窗体尺寸
int x,y,nWidth,nHeight;
if(lprcWnd == NULL)
{
x = y =nWidth = nHeight = CW_USEDEFAULT;
}
else
{
x = lprcWnd->left;
y = lprcWnd->top;
nWidth = lprcWnd->right - lprcWnd->left;
nHeight = lprcWnd->bottom - lprcWnd->top;
}
///如果有菜单,加载菜单,并作为窗体菜单
if(nMenuID > 0 )
m_hMenu = LoadMenu(m_hInstance ,MAKEINTRESOURCE(nMenuID));
///检测类名是否已经注册
CheckClass(MY_WND_CLASS_NAME);
///创建窗体
m_hWnd = CreateWindowEx(dwExStyle , MY_WND_CLASS_NAME ,lpText ,dwStyle ,x, y ,
nWidth ,nHeight ,hParent ,m_hMenu , m_hInstance ,this);
return m_hWnd;
}
HWND CMyWnd::CreateEX(DWORD dwStyle ,int x,int y , int nWidth ,int nHeight ,HWND hParent)
{
///创建窗体的重载函数
RECT rc = {x , y , x + nWidth , y + nHeight};
return CreateEx(NULL , 0 , _T("MyWnd") , dwStyle ,&rc ,hParent , 0);
}
void CMyWnd::Destroy()
{
///销毁窗体
if(m_hWnd)
{
DestroyWindow(m_hWnd);
m_hWnd = NULL;
}
}
BOOL CMyWnd::Show(int nCmd)
{
///显示或隐藏窗口
return ShowWindow(m_hWnd , nCmd);
}
HWND CMyWnd::GetHwnd()
{
//返回窗体句柄
return m_hWnd;
}
CMyWnd::operator HWND() const
{
return m_hWnd;
}
BOOL CMyWnd::preprocessMsg(HWND hWnd , UINT nMsg ,WPARAM wp ,LPARAM lp , LRESULT *pResult)
{
///返回所有消息处理前,会调用此函数
//返回TRUe代表继续由相应消息响应函数处理,否则不用再处理
///消息的返回值由pResult中返回
return TRUE;
}
LRESULT CMyWnd::OnCreate(HWND hWnd)
{
//WM_CREATE消息的响应函数
return 0;
}
BOOL CMyWnd::OnDestroy()
{
return true;
}
BOOL CMyWnd::OnCommand(int nCndID)
{
return true;
}
BOOL CMyWnd::OnPaint()
{
return true;
}
BOOL CMyWnd::OnEraseBk(HDC hDC)
{
return true;
}
BOOL CMyWnd::OnTimer(int nID)
{
return true;
}
BOOL CMyWnd::CheckClass(LPCTSTR lpClassName)
{
///检测类名,如果没有注册,则注册
WNDCLASS wc = {0};
if(!GetClassInfo(m_hInstance , lpClassName ,&wc))///GetClassInfo()函数用于检测一个类是否被注册
{
wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = lpClassName;
return RegisterClass(&wc);
}
return true;
}
LRESULT CALLBACK CMyWnd::WndProc(HWND hWnd , UINT nMsg , WPARAM wp ,LPARAM lp)
{
///消息处理的约定:
///1、派生类处理了某个消息处理函数后,无需再调用基类处理,调用基类意味着默认处理
///2、消息处理,除特殊消息外,返回TRUE代表要调用默认处理,否则不调用默认处理
LRESULT lResult = 0 ;
BOOL bCallDefault = true;
///取出和句柄相对应的类
CMyWnd *pWnd = (CMyWnd*)GetProp(hWnd ,MY_WND_PROP_NAME);////GetProp()函数的作用
if(pWnd == NULL)
{
if(nMsg != WM_CREATE)
{
return DefWindowProc(hWnd ,nMsg,wp , lp);
}
else
{
LPCREATESTRUCT pSt = (LPCREATESTRUCT)lp;
pWnd = (CMyWnd*)pSt->lpCreateParams;
SetProp(hWnd ,MY_WND_PROP_NAME ,pWnd);
}
}
if(!pWnd->preprocessMsg(hWnd ,nMsg ,wp ,lp ,&lResult))
return lResult;
///处理消息
switch(nMsg)
{
case WM_CREATE:
{
pWnd->m_hWnd = hWnd;
lResult = pWnd->OnCreate(hWnd);
bCallDefault = false;
break;
}
case WM_DESTROY:
bCallDefault = pWnd->OnDestroy();
break;
case WM_COMMAND:
bCallDefault = pWnd->OnCommand(LOWORD(wp));
break;
case WM_PAINT:
bCallDefault = pWnd->OnPaint();
break;
case WM_ERASEBKGND:
bCallDefault = pWnd->OnEraseBk((HDC)wp);////???????????
break;
case WM_CLOSE:
pWnd->Destroy();
bCallDefault = false;
break;
case WM_TIMER:
bCallDefault = pWnd->OnTimer((int)wp);
break;
default:
break;
}
///根据消息处理结果调用默认的处理过程,或者直接返回
if(bCallDefault)
return DefWindowProc(hWnd , nMsg , wp , lp);
else
return lResult;
}
// ChildWnd1.h: interface for the CChildWnd1 class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CHILDWND1_H__179CB7BA_1D79_40C7_A603_9AD343A003D5__INCLUDED_)
#define AFX_CHILDWND1_H__179CB7BA_1D79_40C7_A603_9AD343A003D5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MyWnd.h"
class CChildWnd1 : public CMyWnd
{
public:
CChildWnd1();
virtual ~CChildWnd1();
BOOL OnEraseBk(HDC hDC);
};
#endif // !defined(AFX_CHILDWND1_H__179CB7BA_1D79_40C7_A603_9AD343A003D5__INCLUDED_)
// ChildWnd1.cpp: implementation of the CChildWnd1 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ChildWnd1.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CChildWnd1::CChildWnd1()
{
}
CChildWnd1::~CChildWnd1()
{
}
BOOL CChildWnd1::OnEraseBk(HDC hDC)
{
///测试窗体1绘制背景为绿色
HBRUSH hb = CreateSolidBrush(RGB(0,127,0));
RECT rect = {0};
GetClientRect(m_hWnd , &rect);
FillRect(hDC ,&rect , hb);
DeleteObject(hb);
return 0 ;
}
// ChildWnd2.h: interface for the CChildWnd2 class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CHILDWND2_H__B96FDC39_0CE0_45FA_B2FB_8CBF93346686__INCLUDED_)
#define AFX_CHILDWND2_H__B96FDC39_0CE0_45FA_B2FB_8CBF93346686__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MyWnd.h"
class CChildWnd2 : public CMyWnd
{
public:
CChildWnd2();
virtual ~CChildWnd2();
BOOL OnEraseBk(HDC hDC);
};
#endif // !defined(AFX_CHILDWND2_H__B96FDC39_0CE0_45FA_B2FB_8CBF93346686__INCLUDED_)
// ChildWnd2.cpp: implementation of the CChildWnd2 class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ChildWnd2.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CChildWnd2::CChildWnd2()
{
}
CChildWnd2::~CChildWnd2()
{
}
BOOL CChildWnd2::OnEraseBk(HDC hDC)
{
///测试窗体2绘制背景为lan色
HBRUSH hb = CreateSolidBrush(RGB(0,0,127));
RECT rect = {0};
GetClientRect(m_hWnd , &rect);
FillRect(hDC ,&rect , hb);
DeleteObject(hb);
return 0 ;
}
WindowDemo.cpp中
// WindowDemo.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "MainWnd.h"
//#include<tchar.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
///建立主窗体
CMainWnd wnd;
HWND hWnd = wnd.CreateEx(hInstance , 0 , _T("主窗体") , WS_OVERLAPPEDWINDOW , NULL ,NULL, IDR_MAIN);
wnd.Show(SW_SHOW);
if(!hWnd)
{
MessageBox(NULL,_T("创建主窗体时错误..."),NULL ,MB_OK);
return 0 ;
}
///消息循环
MSG msg = {0};
while(GetMessage(&msg ,NULL ,0 , 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}

本文档通过VC6平台,演示了如何利用Win32 API创建、销毁、显示和隐藏窗体。首先,创建一个Win32 Application项目,并设置简单的菜单资源。菜单项包括创建、销毁、显示和隐藏窗体的功能。接着,添加CMainWnd、CChildWnd1和CChildWnd2三个类,分别用于主窗口和两个子窗口的管理。

414

被折叠的 条评论
为什么被折叠?



