通过钩子函数子类化窗口,不知为何,窗口自动关闭 20

#include<windows.h>HHOOKg_hHook;//窗口函数LRESULTCALLBACKMainWndProc(HWND,UINT,WPARAM,LPA... #include <windows.h>
HHOOK g_hHook;
//窗口函数
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

//钩子函数
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_CREATEWND)
//在窗口创建时子类化
::SetWindowLong((HWND)wParam, GWL_WNDPROC, (DWORD)MainWndProc);
return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
char szClassName[] = "MainWClass";
WNDCLASSEX wndclass;

// 用描述主窗口的参数填充WNDCLASSEX结构
wndclass.cbSize = sizeof(wndclass); // 结构的大小
wndclass.style = CS_HREDRAW|CS_VREDRAW; // 指定如果大小改变就重画
wndclass.lpfnWndProc = ::DefWindowProc; // 窗口函数指针
wndclass.cbClsExtra = 0; // 没有额外的类内存
wndclass.cbWndExtra = 0; // 没有额外的窗口内存
wndclass.hInstance = hInstance; // 实例句柄
wndclass.hIcon = ::LoadIcon(NULL,
IDI_APPLICATION); // 使用预定义图标
wndclass.hCursor = ::LoadCursor(NULL,
IDC_ARROW); // 使用预定义的光标
wndclass.hbrBackground = (HBRUSH)
::GetStockObject(WHITE_BRUSH); // 使用白色背景画刷
wndclass.lpszMenuName = NULL; // 不指定菜单
wndclass.lpszClassName = szClassName ; // 窗口类的名称
wndclass.hIconSm = NULL; // 没有类的小图标

// 注册这个窗口类
::RegisterClassEx(&wndclass);

//-------------------------------gouzi-----------------------------//
g_hHook = ::SetWindowsHookEx(WH_CBT, HookProc, NULL, ::GetCurrentThreadId());
// 创建主窗口
HWND hwnd = ::CreateWindowEx(
0, // dwExStyle,扩展样式
szClassName, // lpClassName,类名
"My first Window!", // lpWindowName,标题
WS_OVERLAPPEDWINDOW, // dwStyle,窗口风格
CW_USEDEFAULT, // X,初始 X 坐标
CW_USEDEFAULT, // Y,初始 Y 坐标
CW_USEDEFAULT, // nWidth,宽度
CW_USEDEFAULT, // nHeight,高度
NULL, // hWndParent,父窗口句柄
NULL, // hMenu,菜单句柄
hInstance, // hlnstance,程序实例句柄
NULL) ; // lpParam,用户数据
::UnhookWindowsHookEx(g_hHook);
//-------------------------------gouzi-----------------------------//
// 显示窗口,刷新窗口客户区
::ShowWindow(hwnd, nCmdShow);
::UpdateWindow(hwnd);

// 从消息堆中取出消息
MSG msg;
while(::GetMessage(&msg, NULL, 0, 0))
{
// 转化键盘消息
::TranslateMessage(&msg);
// 将消息发送到相应的窗口函数
::DispatchMessage(&msg);
}
// 当GetMessage返回0时程序结束
return msg.wParam;
}

LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{

case WM_DESTROY: // 正在销毁窗口
// 向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
::PostQuitMessage(0) ;
return 0 ;
}

// 将我们不处理的消息交给系统做默认处理
return ::DefWindowProc(hwnd, message, wParam, lParam);
}
找了几个小时都想不通为何自动关闭
展开
 我来答
约定20125
2018-02-16 · TA获得超过1.5万个赞
知道大有可为答主
回答量:1.1万
采纳率:96%
帮助的人:2924万
展开全部
子类化,通俗来讲就是用自己的窗口处理函数来处理特定消息,并将自己其他消息还给标准(默认)窗口处理函数。在SDK中,通过SetWindowLong来指定一个自定义窗口处理函数:SetWindowLong(hwnd, GWL_WNDPROC, (LONG)UserWndProc);。可是到了MFC中,大部分基础的东西都被封装起来了,那么,这是该怎么实现子类化呢?
先来看一个例子:
要求:定义一个Edit控件,让它能够对输入进行特定的处理输入进行处理-----只能输入英文字母,对其他输入作出提示。
分析:1)处理输入当然是响应WM_CHAR消息了,然后对输入字符进行判断,并做相应处理。那么,我们有怎么才能让Edit自己处理输入呢?
2)我们知道Windows为我们设计Edit控件时,已经将常用操作通过成员函数的形式封装在CEdit类中了,直接由CEdit生成的对象自己并不能改变原有方法或是定制自己的方法(除了虚函数,但有时我们想实现的并不是虚函数啊!),那么现在想达到这些情况应该怎么办呢?这就用到本篇文章的主题-----MFC子类化。
3)我们可以从CEdit类派生一个新类CSuperEdit,然后通过子类化方法是Edit窗口来使用我们指定的消息处理函数。
实现:先CSuperEdit,并为其添加WM_CHAR消息响应函数,这样CSuperEdit对象就拥有了自己WM_CHAR响应函数(这正是子类化的效果所在----面向对象----自己的方法封装在自己的类中),然后在其父窗口类(这里我们用一个基于对话框的MFC程序)中声明一个CSuperEdit类对象m_edit,当然m_edit需要和一个实际存在的窗口关联起来,因此,在CXXXDialog::OnInitDialogj中添加:m_edit.SubclassDlgItem(IDC_EDIT1,this);这样
就将m_edit这个c++对象和IDC_EDIT1窗口关联起来了,然后我们只需要在CSuperEdit::OnChar()中添加相应的操作就OK了。
追问
麻烦你看清我的问题好吗
这个代码的窗口自动关闭
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式