博文
CWnd使用(2008-03-17 16:24:00)
摘要:一般情况下开始学习MFC时都知道CWnd是MFC窗口类的基类,稍微深入学习后突然想从最基本的学起,即自己从CWnd派生一个窗口类而不是总通过AppWizard产生一个预先定义好的窗口类,其实更加赤裸点就是直接把CWnd做为窗口类,以下为范例程序:
#include <afxwin.h>
class CMyApp:public CWinApp
{
public:
BOOL InitInstance();
virtual int ExitInstance();
};
CMyApp theApp;
BOOL CMyApp::InitInstance()
{
CWnd* pMainWnd=new CWnd;
pMainWnd->CreateEx(0,0,"MyWnd",
WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL);
this->m_pMainWnd=pMainWnd;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
&nb......
MFC is back(2007-11-21 12:09:00)
摘要:Hello again. My name is Ale Contenti, and I’m the Dev Lead for the VC++ Libraries. I’m writing this blog entry from my hotel room in Barcelona. Steve Teixeira and I are here for TechEd Developers Europe. Let me tell you that the atmosphere here is just great! Lots of people and a lot of Visual Studio and C++ users. Lots of interest in Visual Studio 2008 and all the new features and functionality we’ve added to the product.
Kate Gregory, Steve and I covered more than 7 talks about different C++ topics, ranging from debugging to interop to MFC. My main talk was about “MFC Updates for Visual Studio 2008 and Beyond”. In this session I introduced the major new features we’re implementing for MFC. With these features, developers will be able to create modern applications that leverage the “look and feel” of Microsoft Office, Internet Explorer and Visual Studio.
My MFC talk was in a pretty big room, and the audience was extremely interested! It was great to......
转载 MFC消息详解 (2007-09-05 14:48:00)
摘要:MFC消息详解
1. 怎样使用MFC发送一个消息用MFC发送一个消息的方法是,
首先,应获取接收消息的CWnd类对象的指针;
然后,调用CWnd的成员函数SendMessage( )。
LRESULT Res=pWnd->SendMessage(UINT Msg, WPARAM wParam, LPARAM lParam);
pWnd指针指向目标CWnd类对象。变量Msg是消息,wParam和lParam变量包含消息的参数,如鼠标单击哪里或选择了什么菜单项。目标窗口返回的消息结果放在变量Res中。
发送消息到一个没有CWnd类对象的窗口,可以用下列目标窗口的句柄直接调用Windows API:
LRESULT Res=::SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
这里的hWnd是目标窗口的句柄。
2. 怎样用MFC寄送一个消息
用MFC寄送一个消息与发送一个消息几乎相同,但寄送时用PostMessage( ) ,而不是用SendMessage( );返回值Res也不一样,Res不是一个由目标窗口返回的值,而是一个布尔值,用来表示消息是否成功地放到消息队列中。
3. 检索一个寄送消息
正常情况下,一旦消息被寄送后,应用程序在后台发送它。但是在特殊情况下,需要你自己去删除一个消息,例如想在应用程序接收到某种消息之前停止应用程序。有两种......
float ToolBar && dock ToolBar(2007-09-01 11:21:00)
摘要:A docked toolbar is a child of the frame window it's docked to, but a floating toolbar is a child of the mini frame window that surrounds it. The mini frame window is a popup window owned by the frame window, but it's not a child of the frame window. (A popup window is a window with the style WS_POPUP; a child window has the WS_CHILD style instead.) The distinction is important because popup windows owned by a frame window are destroyed before the frame window is destroyed. Child windows, on the other hand, are destroyed after their parents are destroyed. A floating toolbar no longer exists when the frame window's OnDestroy function is called.......
消息传递过程(2007-09-01 01:05:00)
摘要:
据说是在Run中调用AfxWndProc(侯捷说的我在源码中找了会没找到,也不晓得是哪个间接调用的),在该函数里面接着调用AfxCallWndProc,然后AfxCallWndProc中有这么一段
// special case for WM_INITDIALOG
CRect rectOld;
DWORD dwStyle = 0;
if (nMsg == WM_INITDIALOG)
_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);
// delegate to object's WindowProc
lResult = pWnd->WindowProc(nMsg, wParam, lParam);
// more special case for WM_INITDIALOG
if (nMsg == WM_INITDIALOG)
_AfxPostInitDialog(pWnd, rectOld, dwStyle);
如果不是WM_INITDIALOG消息则调用CWnd的WindowProc,这时就有点迷惑了,应该说CCmdTarget是处理消息的基类其中的OnCmdMsg为什么不先调用呢,其实我也不清楚,查看了源代码后发现在WindowProc中会判断消息的类型里面有这么段:
CWnd::WindowProc
if (message == WM_COMMAND)
{
if (OnCommand(wParam, lParam))
{
lResult = 1;
goto LReturnTrue;
}
......
MDI,SDI创建过程中的一点不同(2007-08-31 12:51:00)
摘要:CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_MDISQUTYPE,
RUNTIME_CLASS(CSquaresDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CSquaresView));
AddDocTemplate(pDocTemplate);
// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
m_pMainWnd = pMainFrame;
。。。。。。。。
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The main window has been initialized, so show and update it.
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
上面为MDI,下面为SDI
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CSquaresDoc......
回调函数在MFC中的使用(2007-08-26 23:42:00)
摘要:回调函数的简单定义就是你定义的由Windows来调用。以下两个函数摘自《Programming Windows with MFC》,这里暂且不管函数的具体作用,在FillListBox中有一个API函数,它调用的回调函数是EnumFontFamProc,回调函数的声明形式一般都是相对固定的,具体可以参考MSDN。
static int CALLBACK EnumFontFamProc (ENUMLOGFONT* lpelf,
NEWTEXTMETRIC* lpntm, int nFontType, LPARAM lParam);
void CMainWindow::FillListBox ()
{
m_wndListBox.ResetContent ();
CClientDC dc (this);
::EnumFontFamilies ((HDC) dc, NULL, (FONTENUMPROC) EnumFontFamProc,
(LPARAM) this);
}
int CALLBACK CMainWindow::EnumFontFamProc (ENUMLOGFONT* lpelf,
NEWTEXTMETRIC* lpntm, int nFontType, LPARAM lParam)
{
CMainWindow* pWnd = (CMainWindow*) lParam;
if ((pWnd->m_wndCheckBox.GetCheck () == BST_UNCHECKED) ||
(nFontType & TRUETYPE_FON......
CWnd及窗口产生和销毁过程(2007-08-25 19:00:00)
摘要:昨天去新华书店看的今天趁还记得就写下了.
窗口创建:首先定义一个CWnd对象,然后调用CWnd::Create,其实Create又会调用CreateEx,与之对应的API函数也是这样,在CreateEx调用AfxCtxCreateWindowEx之前会调用PreCreateWindow,这个时候偶CWnd对应的窗口的句柄还未被Windows分配,之后调用AfxCtxCreateWindowEx,在调用这个函数的过程中会发送WM_CREATE消息从而引发OnCreate函数调用注意调用OnCreate时CWnd中的m_hWnd已经有值了,在OnCreate中可以进行一些初始化以及创建字窗口之类的事情。至此窗口创建完毕。
窗口销毁:可以发送一个WM_CLOSE消息给指定窗口使其调用OnClose函数,此函数中会发送WM_DESTROY从而引发OnDestroy的调用,该函数又会引发最后一个消息WM_NCDESTROY的发送,OnNcDestroy即被调用,在OnNcDestroy的最后会调用PostNcDestroy,CWnd的PostNcDestroy为
void CWnd::PostNcDestroy()
{
// default to nothing
},什么也不做,但是CFrameWnd重载了此函数
void CFrameWnd::PostNcDestroy()
{
// default for frame windows is to allocate them on the heap
// the default post-cleanup is to 'delete this'.
// never explicitly call 'delete' on a CFrameWnd, use DestroyWindow instead
delete this;
}即我们看到的在App中new的Frame没有删除就是这个原因,但是我们自己从CWnd派生的窗口就不同了,如果你new了就要delete,而且最好就是在这个函数里delete。......
VC截取屏幕(2007-08-18 01:23:00)
摘要:
一直对GID 不是很懂,今天狠下心来看了一天的GDI,主要是参照着MSDN看,感觉还是有点收获的。根据MSDN写了一个小小的程序,仅仅就是截取屏幕,另外可以将其保存到剪贴板里。
以下为源代码:
// Capturing_Image.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Capturing_Image.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void CaptureScreen(HWND,HDC);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,......
MFC学习之--MFC窗口过程(2007-08-05 00:23:00)
摘要:所有的消息都送给窗口过程处理,MFC的所有窗口都使用同一窗口过程,消息或者直接由窗口过程调用相应的消息处理函数处理,或者按MFC命令消息派发路径送给指定的命令目标处理。
那么,MFC的窗口过程是什么?怎么处理标准Windows消息?怎么实现命令消息的派发?
MFC窗口过程的指定
从前面的讨论可知,每一个“窗口类”都有自己的窗口过程。正常情况下使用该“窗口类”创建的窗口都使用它的窗口过程。
MFC的窗口对象在创建HWND窗口时,也使用了已经注册的“窗口类”,这些“窗口类”或者使用应用程序提供的窗口过程,或者使用Windows提供的窗口过程(例如Windows控制窗口、对话框等)。那么,为什么说MFC创建的所有HWND窗口使用同一个窗口过程呢?
在MFC中,的确所有的窗口都使用同一个窗口过程:AfxWndProc或AfxWndProcBase(如果定义了_AFXDLL)。它们的原型如下:
LRESULT CALLBACK
AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK
AfxWndProcBase(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
这两个函数的原型都如符合windows的窗口过程函数原型。
如果动态链接到MFC DLL(定义了_AFXDLL),则AfxWndProcBase被用作窗口过程,否则AfxWndProc被用作窗口过程。AfxWndProcBase首先使用宏AFX_MANAGE_STATE设置正确的模块状态,然后调用AfxWndProc。
下面,假设不使用MFC DLL,讨论MFC如何使用AfxWndProc取代各个窗口的原窗口过程。
窗口过程的取代发生在窗口创建的过程时,使用了子类化(Subclass)的方法。所以,从窗口的创建过程来考察取代过程。从前面可以知道,窗口创建最终是通过调用CWnd::CreateEx函数完成的,分析该函数的流程:
CREATESTRUCT结构类型的变量cs包含了传递给窗口过程的初始化参数。CREATESTRUCT结构描述了创建窗口所需要的信息,定义如下:
typedef struct tagCREAT......