MFC对话框使用技巧

1. 在任务栏隐藏对话框

ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);


2. 使对话框为顶层窗口

SetWindowPos(&this->wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);


3. 在运行时添加最大化,最小化按钮

SetWindowLong(this->m_hWnd, GWL_STYLE,
GetWindowLong(this->m_hWnd, GWL_STYLE) |
WS_MINIMIZEBOX | WS_MAXIMIZEBOX); 
UpdateWindow();



4. 使能对话框右上角关闭按钮


在OnInitDialog中

方法一:
CMenu* menu = GetSystemMenu(FALSE);
menu->ModifyMenu(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED );

方法二:
CMenu* menu = GetSystemMenu(FALSE);
menu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);


5. 当对话框一部分在屏幕外时,显示全部对话框

SendMessage(DM_REPOSITION);


6. 改变鼠标外形


添加 WM_SETCURSOR 消息映射函数

BOOL CTest6Dlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HELP));

return 0; 
}


7. 改变对话框背景色和文本颜色


在CTest6App的InitInstance中添加

SetDialogBkColor(RGB(255,0,0), RGB(0,255,0));


8. 改变对话框caption上的图标


导入自己的图标资源到工程中,把原来ID为 IDR_MAINFRAME 的资源删除,把新的图标的ID命名为IDR_MAINFRAME


9. 在主对话框显示前,显示一个login对话框


BOOL CTest6App::InitInstance()
{
//...
int nResponse;
CLoginDlg loginDlg;

nResponse = loginDlg.DoModal();
if (nResponse == IDOK)
{
}
if (nResponse == IDCANCEL)
{
return FALSE;
}

CTest6Dlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK )
{
}
else if (nResponse == IDCANCEL)
{
}
return FALSE;
}

然后重载CLoginDlg对话框的哦OnOK(),在其中判断条件
void CLoginDlg::OnOK() 
{
if (条件满足)
CDialog::OnOK();
else 
AfxMessageBox(_T("invalid password!"));
}



10. 在对话框中添加工具栏


方法一:添加以下代码到 OnInitDialog 中

if ( !m_wndToolBar.Create(this) || !m_wndToolBar.LoadToolBar(IDR_TOOLBAR1) )
{
TRACE0("Failed to Create Dialog Toolbar\n");
EndDialog(IDCANCEL);
}

CRect rcClientOld; // 久客户区RECT
CRect rcClientNew; // 加入TOOLBAR后的CLIENT RECT
GetClientRect(rcClientOld); //
// Called to reposition and resize control bars in the client area of a window
// The reposQuery FLAG does not really traw the Toolbar. It only does the calculations.
// And puts the new ClientRect values in rcClientNew so we can do the rest of the Math.
//重新计算RECT大小
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,
AFX_IDW_CONTROLBAR_LAST,
0,
reposQuery,
rcClientNew);

// All of the Child Windows (Controls) now need to be moved so the Tollbar does not cover them up.
//所有的子窗口将被移动,以免被TOOLBAR覆盖
// Offest to move all child controls after adding Tollbar
//计算移动的距离
CPoint ptOffset(rcClientNew.left-rcClientOld.left,
rcClientNew.top-rcClientOld.top);

CRect rcChild;
CWnd* pwndChild = GetWindow(GW_CHILD); //得到子窗口
while(pwndChild) // 处理所有子窗口
{
//移动所有子窗口
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild,FALSE);
pwndChild = pwndChild->GetNextWindow();
}

CRect rcWindow;
GetWindowRect(rcWindow); // 得到对话框RECT
rcWindow.right += rcClientOld.Width() - rcClientNew.Width(); // 修改对话框尺寸
rcWindow.bottom += rcClientOld.Height() - rcClientNew.Height();
MoveWindow(rcWindow,FALSE); // Redraw Window

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

方法二:

http://www.codeproject.com/dialog/dlgtoolstatusbar.asp


11.响应对话框的最大化、最小化、关闭、恢复事件


方法一:添加 WM_SYSCOMMAND 消息映射函数

void CTest6Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ( (nID & 0xFFF0) == IDM_ABOUTBOX )
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
if ( nID == SC_MAXIMIZE )
{
AfxMessageBox(_T("最大化"));
}
else if ( nID == SC_MINIMIZE ) 
{
AfxMessageBox(_T("最小化"));
}
else if ( nID == SC_CLOSE )
{
AfxMessageBox(_T("关闭"));
}

CDialog::OnSysCommand(nID, lParam);
}

方法二:添加 WM_SIZE 消息映射函数

void CTest6Dlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);

if ( nType == SIZE_MAXIMIZED )
{
AfxMessageBox(_T("最大化"));
}
else if ( nType == SIZE_MINIMIZED )
{
AfxMessageBox(_T("最小化"));

else if ( nType == SIZE_RESTORED )
{
AfxMessageBox(_T("恢复"));
}
}


12.代码实现窗口最小化,最大化,关闭


PostMessage(WM_SYSCOMMAND, SC_MINIMIZE);
PostMessage(WM_SYSCOMMAND, SC_MAXIMIZE);
PostMessage(WM_SYSCOMMAND,  SC_CLOSE);


13.按下ESC和ENTER键时禁止关闭对话框


方法一:

(1) 重载OnCancel和OnOk,屏蔽其中的CDialog::OnCancel()和CDialog::OnOk();
(2) 添加以下代码 
void CTest6Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout; //if you have an about dialog
dlgAbout.DoModal();
}
else if ((nID & 0xFFF0) == SC_CLOSE)
{
//用户点击右上角"X"
EndDialog(IDOK); 

}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

方法二:

BOOL CTest6Dlg::PreTranslateMessage(MSG* pMsg)
{
if ( pMsg->message == WM_KEYDOWN )
{
switch(pMsg->wParam)
{
case VK_ESCAPE:
return TRUE; //直接返回TRUE
break;
case VK_RETURN:
return TRUE;
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}

方法三:
Q122489:
How to Disable Default Pushbutton Handling for MFC Dialog
http://support.microsoft.com/kb/122489/en-us


14.在对话框中处理键盘鼠标消息


处理PreTranslateMessage消息

以下代码示例只演示了键盘WM_KEYDOWN消息,你也可以处理鼠标消息,比如WM_LBUTTONDOWN,WM_LBUTTONUP,WM_RBUTTONDOWN等。

BOOL CTest6Dlg::PreTranslateMessage(MSG* pMsg) 

/**********************************************************/
/* 当焦点在combobox(drop down风格)的edit上,响应回车 */ 
/***********************************************************/ 
if ( pMsg->message == WM_KEYDOWN ) 

switch( pMsg->wParam ) 

case VK_RETURN: 
CEdit *pEdit = (CEdit*)m_combo1.GetWindow(GW_CHILD); 
if(pMsg->hwnd == pEdit->m_hWnd ) 

AfxMessageBox("在combobox的edit中按下了Enter!"); 

return TRUE; 



/****************************************/ 
/* 
ALT为WM_SYSKEYDOWN  */ 
/****************************************/

if( pMsg->message == WM_SYSKEYDOWN ) 

switch( pMsg->wParam ) 

case VK_F1: 
if(::GetKeyState(VK_MENU) < 0)//ALT+F1

AfxMessageBox("按下了ALT+F1"); 
return TRUE; 




/****************************************/ 
/* 在clistctrl中按ctrl+A选中所有项 */ 
/****************************************/ 
if( pMsg->message == WM_KEYDOWN ) 

if(pMsg->hwnd == GetDlgItem(IDC_LIST1)->m_hWnd) 

switch( pMsg->wParam ) 

case 65://A 
if(::GetKeyState(VK_CONTROL) < 0)//Shift+enter 

for(int i=0; i<m_list.GetItemCount(); i++) 

m_list.SetItemState(i, LVIS_SELECTED|LVIS_FOCUSED, 
LVIS_SELECTED|LVIS_FOCUSED); 


return TRUE; 




/****************************************/ 
/* 当焦点在combobox,弹出自定义菜单 */ 
/****************************************/ 
if(pMsg->message == WM_RBUTTONDOWN) 

CEdit *pEdit = (CEdit*)m_combo1.GetWindow(GW_CHILD); 
if(pMsg->hwnd == pEdit->m_hWnd) 

DWORD dwPos = GetMessagePos(); 
CPoint point( LOWORD(dwPos), HIWORD(dwPos) ); 
ScreenToClient(&point); 
ClientToScreen(&point); 

CMenu menu; 
VERIFY( menu.LoadMenu( IDR_MENU1 ) ); 
CMenu* popup = menu.GetSubMenu(0); 
ASSERT( popup != NULL ); 
popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this ); 



return CDialog::PreTranslateMessage(pMsg); 
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值