MFC开发的一些记录,方便查阅

1.窗口句柄获取

通过窗口句柄函数获取窗口句柄,主要为了某些情况下,需要控制窗体的展现等级

GetForegroundWindow() 返回 Windows 系统的当前激活的窗口句柄。

GetActiveWindow() 返回自己程序的当前激活窗口的句柄。

GetTopWindow()函数成功,返回值为在Z序顶部的子窗口句柄

WindowsAPI-获得当前活动窗口(运行自身消息循环的窗体)的句柄_iswindow winapi-CSDN博客

 (1)FindWindowA函数

        今天改一个bug,是窗口层级的问题,两个窗口(一个进度条窗口A,一个MsgBoxTip提示窗口在A上层)是一个上下的层级关系(只能操作其中一个,不能操作另外一个窗口),但最后展现效果是一个并列的关系(两个窗口都可以操作)。初步就是怀疑MsgBoxTip的父窗口句柄设置错误,但又获取不到窗口A句柄,最终使用FindWindowA函数获取到了A窗口句柄。

Sleep(100);
HWND hWnd = FindWindowA(NULL, "操作进行中,请稍候...");//查找进度条弹窗A的句柄
UI::MsgBoxTip(hWnd, L"操作失败!");//提示弹窗并设置父句柄

         其中使用Sleep,是该弹窗A与MsgBoxTip不在一个线程,会出现MsgBoxTip先于弹窗A的情况,导致FindWindowA失败。

(2)线程窗口导致的弹窗显示异常

        对于线程窗口,中间遇见过一种情况:一个函数里,中间有一段代码开了一个线程窗口,线程窗口结束,继续执行后续代码,后续代码给了一个MsgBoxTip,尽管设置了主窗口句柄为父句柄,但仍旧没有实现模态框的效果。后面调试,加上了一个SetActiveWindow函数,效果正常。猜测线程窗口结束后,程序的线程间资源切换有点异常,设置父窗口失效,导致该现象。


	ProgressDlgParams& dlgParams = getProgressDlgParams();
	dlgParams.m_nStep = 1;
	dlgParams.m_strCaption = "操作进行中,请稍候...";
	dlgParams.m_strMessage = "请稍候...";
	dlgParams.m_bBottomMessage = FALSE;
	dlgParams.m_bInfinite = TRUE;
	dlgParams.m_bShowCancel = TRUE;

	startProgress("线程启动", 0, 100, true);
	endProgress();

	SetActiveWindow();//不进行当前窗口激活,下面MsgBoxSucceed不会形成模态的效果
	UI::MsgBoxSucceed(AfxGetApp()->m_pMainWnd->GetSafeHwnd(), L"数据导出完成!");

2.SendMessage附带消息

可以使用如下格式附带字符串消息,给目标句柄:

CString str1 = _T("123");
CString str2 = _T("hello");
::SendMessage(this->GetSafeHwnd(), TTMSG_WARNLIST1, (WPARAM)(LPCTSTR)str1, (LPARAM)(LPCTSTR)str2); //发送消息方式1

消息附带格式详细链接:MFC实例:SendMessage 发送字符串,结构体,数字_sendmessage发送字符串-CSDN博客
 

 3.CString和数字互转

CString strTmp = "",str1="";
str1.Format("%I64u", m_iID);//int64
strTmp = strTmp + str1 + "-";
str1.Format("%f", m_dMoveToward);//f


4.mfc界面展示上角标、下角标

Unicode的上标与下标有相应编码对应,然后使用长字符进行一个对应转化。

wchar_t OptionText=‘\U00B3’;
CString cstring(OptionText); //然后再把该string赋值给需要显示的界面要素字段

5.OnCommand消息,实现界面不同控件事件响应的集中化处理

给mfc界面增加了三个按钮,但这三个按钮的实现函数是相似的,不想呆呆的写3个click响应消息去处理,想进行集中处理,网上搜了下,找到了OnCommand方式:

//一个重载虚函数,可进行相应的消息重写
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);

 wParam :低位表示菜单项、控件、或者快捷键的 ID 值,如果表示的是控件的话,高位值代表相应的通知消息值,如果地位表示快捷键的话,高位值为 1,如果低位值是菜单的话,高位值就为 0 。
lParam:如果 WM_COMMAND 来自控件的话 lParam 就是发送这个 WM_COMMAND 消息的控件的句柄,否则为 0 。

根据此,写出如下函数,完成了集中处理。


BOOL XXXXDlg::OnCommand(WPARAM wParam, LPARAM lParam) {
	//获取触发的控件ID
	UINT ctrlId = LOWORD(wParam);
	//判断是否要进行处理
	if (HIWORD(wParam)==BN_CLICKED) {
		if (ctrlId == IDC_BUTTON3) {
			OnBnClickedLayerListDlg(3);
		}
		else if (ctrlId == IDC_BUTTON2) {
			OnBnClickedLayerListDlg(2);
		}
		else if (ctrlId == IDC_BUTTON1) {
			OnBnClickedLayerListDlg(1);
		}
	}
	return CDialogBase::OnCommand(wParam, lParam);
}

 附上一个mfc消息过程的链接:MFC消息详解 (WindowProc|OnCommand|OnNotify)_mfc 子窗口windowproc未被调用-CSDN博客

 6.dlg.DoModal()失败的问题

今天遇见一个bug,界面点击按钮DoModal()出一个窗口时,发现只有第一次窗口能够弹出成功,后续点击该按钮未有反应(后续DoModal()返回值=-1),经排查是窗口资源异常导致的,致使DoModal窗口时未能正确找到窗口ID进行映射,表现效果就是弹窗显示失败。

这里面主要牵涉资源模块的知识点:

1.HINSTANCE hDll = GetModuleHandleA("useDll.dll");AfxSetResourceHandle(hDll);获取相应dll的资源模块句柄,并设置目前使用句柄。

2.HINSTANCE hDllTst = AfxGetResourceHandle();获取当前的使用资源模块句柄。

3.DoModal()调用显示窗口资源后,会修改当前的使用资源模块,第一次窗口能显示成功而后续失败,也是该原因导致的。所以在DoModal调用前设置当前所需的资源句柄,即可解决。

调试过程代码如下:

void OnBnClickedBtnEditAdd()
{
    //获取当前dll的资源模块句柄
	HINSTANCE hDll = GetModuleHandleA("curdll.dll");

    //获取当前使用的资源模块句柄
    //第一次调用:hDll =curdll.dll句柄
    //第二次调用:hDll =start.exe句柄
	HINSTANCE hDllTst = AfxGetResourceHandle();

    //设置当前所使用的资源模块句柄
	//AfxSetResourceHandle(hDll);

	CDlg dlg( this);
    //第一次调用:当前句柄hDll =curdll.dll,窗口ID加载正常,窗口弹出
    //第二次调用:当前句柄hDll =start.exe,窗口ID加载失败,窗口异常返回-1
	int resDlg=dlg.DoModal();

    //获取当前dll的资源模块句柄
    //第一次调用:hDllTst1 =start.exe句柄,这里改变了当前资源句柄值,导致第二次使用窗口资源加载失败
	HINSTANCE hDllTst1 = AfxGetResourceHandle();

	if (resDlg != IDOK)
	{
		return;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巨菜的阿豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值