[转]vc对话框使用小技巧
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); } |