如何有效地使用对话框
译者:徐景周 (原作:VGirish )
Q:如何在对话框中加入工具条
在 OnInitDialog 中加入下面代码:
BOOL CYourDlg::OnInitDialog() { CDialog::OnInitDialog(); // Create the toolbar. To understand the meaning of the styles used, you // can take a look at the MSDN for the Create function of the CToolBar class. ToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS |CBRS_FLYBY | CBRS_BORDER_BOTTOM); // I have assumed that you have named your toolbar''s resource as IDR_TOOLBAR1. // If you have given it a different name, change the line below to accomodate // that by changing the parameter for the LoadToolBar function. ToolBar.LoadToolBar(IDR_TOOLBAR1); CRect rcClientStart; CRect rcClientNow; GetClientRect(rcClientStart); // To reposition and resize the control bar RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,0, reposQuery, rcClientNow); CPoint ptOffset(rcClientNow.left - rcClientStart.left,rcClientNow.top-rcClientStart.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); rcWindow.right += rcClientStart.Width() - rcClientNow.Width(); rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height(); MoveWindow(rcWindow, FALSE); // And position the control bars RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); return TRUE; // return TRUE unless you set the focus to a control }
Q:如何改变对话框的形状?
可用下面一些函数:
CreatePolygonRgn
CreateRectRgn
CreateRoundRectRgn 等.
CRgn m_rgn; // Put this in your dialog''s header file. i.e. a member variable // This Gets the size of the Dialog: This piece of code is to be placed in the // OnInitDialog Function of your dialog. CRect rcDialog GetClientRect(rcDialog); // The following code Creates the area and assigns it to your Dialog m_rgn.CreateEllipticRgn(0, 0, rcDialog.Width(), rcDialogHeight()); SetWindowRgn(GetSafeHwnd(), (HRGN) m_rgn, TRUE);
Q:如何实现非客户区移动?
可用下面二种方法
// Handler for WM_LBUTTONDOWN message void CYourDialog::OnLButtonDown(UINT nFlags, CPoint point) { CDialog::OnLButtonDown(nFlags, point); PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y)); } // Handler for WM_NCHITTEST message LONG CYourDialog::OnNcHitTest( UINT uParam, LONG lParam ) { int xPos = LOWORD(lParam); int yPos = HIWORD(lParam); UINT nHitTest = CDialog::OnNcHitTest(CSize(xPos, yPos)); return (nHitTest == HTCLIENT) ? HTCAPTION : nHitTest; }
Q:如何使对话框初始为最小化状态?
在 OnInitDialog 中加入下面代码:
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, NULL);
Q:如何限定对话框大小范围?
在 WM_SIZING中加入下面代码:
void CYourDialog::OnSizing(UINT fwSide, LPRECT pRect) { if(pRect->right - pRect->left <=200) pRect->right = pRect->left + 200; if(pRect->bottom - pRect->top <=200) pRect->bottom = pRect->top + 200; CDialog::OnSizing(fwSide, pRect); }
Q:如何在对话框中加入状态条?
定义 CStatusBar 变量:
CStatusBar m_StatusBar;
定义状态条指定状态:
static UINT BASED_CODE indicators[] = { ID_INDICATOR_CAPS, ID_INDICATOR_NUM };
在 OnInitDialog 中加入下面代码:
m_StatusBar.CreateEx(this,SBT_TOOLTIPS,WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,AFX_IDW_STATUS_BAR); // Set the indicators namely caps and nums lock status m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)); CRect rect; GetClientRect(&rect); m_StatusBar.SetPaneInfo(0,ID_INDICATOR_CAPS,SBPS_NORMAL,rect.Width()/2); m_StatusBar.SetPaneInfo(1,ID_INDICATOR_NUM,SBPS_STRETCH ,rect.Width()/2); RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,ID_INDICATOR_NUM); m_StatusBar.GetStatusBarCtrl().SetBkColor(RGB(180,180,180));
如何有效的使用对话框之二
译者:徐景周 (原作:Nishant S )
本文是《如何有效使用对话框》 一文的继续.
1. 如何有效地使初始窗口不显示
当我们想让窗口初始时不显示时,通常会用ShowWindow(SW_HIDE) ,但实际上还是在启动是可以看到窗口一闪而过的痕迹。所以,可以使用下面的方法来实现它:
(1.1)先在构造函数中设置布乐变量 visible值为false.
visible = false;
(1.2)重载 WM_WINDOWPOSCHANGING,并添加下面代码:
void CTest_deleteDlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) { if(!visible) lpwndpos->flags &= ~SWP_SHOWWINDOW; CDialog::OnWindowPosChanging(lpwndpos); }
(1.3)然后设布尔visible变量值为true,并在要显示窗口时,再用ShowWindow(SW_SHOW)既可。
visible = true; ShowWindow(SW_SHOW);
2. 对话框的全屏显示
对话框的全屏显示可以在OnInitDialog()中用 SetWindowPos 和 HWND_TOPMOST 来实现对话框的重新大小。
BOOL CFullScrDlgDlg::OnInitDialog() { CDialog::OnInitDialog(); //... int cx, cy; HDC dc = ::GetDC(NULL); cx = GetDeviceCaps(dc,HORZRES) + GetSystemMetrics(SM_CXBORDER); cy = GetDeviceCaps(dc,VERTRES) + GetSystemMetrics(SM_CYBORDER); ::ReleaseDC(0,dc); //去除标题和边框 SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & (~(WS_CAPTION | WS_BORDER))); // 置对话框为最顶端并扩充到整个屏幕 ::SetWindowPos(m_hWnd, HWND_TOPMOST, -(GetSystemMetrics(SM_CXBORDER)+1), -(GetSystemMetrics(SM_CYBORDER)+1), cx+1,cy+1, SWP_NOZORDER); //... return TRUE; }
3. 如何在2K/xp下使窗口获取焦点
在2K/XP下我们可以用 AttachThreadInput 和SetForegroundWindow来有效的获取焦点。
//捕捉并设置当前焦点窗口为我们的窗口 AttachThreadInput( GetWindowThreadProcessId( ::GetForegroundWindow(),NULL), GetCurrentThreadId(),TRUE); //置我们的为焦点窗口 SetForegroundWindow(); SetFocus(); //释放thread AttachThreadInput( GetWindowThreadProcessId( ::GetForegroundWindow(),NULL), GetCurrentThreadId(),FALSE);
4. 使你的对话框位于最顶端
可以直接在 OnInitDialog()中用SetWindowPos来实现。
SetWindowPos(&this->wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
5. 如何动态放大/缩小对话框
还是可以用SetWindowPos或MoveWindow来实现它。
void CTest_deleteDlg::OnMakeSmall() { SetWindowPos(NULL,0,0,200,200,SWP_NOZORDER|SWP_NOMOVE); } void CTest_deleteDlg::OnExpand() { SetWindowPos(NULL,0,0,500,300,SWP_NOZORDER|SWP_NOMOVE); }
或:
//伸、缩在IDC_DYCREDITS和IDC_COPYRIGHT两STATIC控件间,做为分隔线 BOOL CAbout::OnInitDialog() { CDialog::OnInitDialog(); //"关于"对话框中对话框可收缩效果 CRect Rect1,Rect2; //对话框收缩时大小 GetDlgItem(IDC_DYCREDITS)->GetWindowRect(Rect1); GetDlgItem(IDC_COPYRIGHT)->GetWindowRect(Rect2); m_nReducedHeight = Rect1.Height()+(Rect1.top -Rect2.bottom)/2; //收缩后窗体高度 dlgRect.bottom -= (Rect1.Height()+(Rect1.top -Rect2.bottom)/2); MoveWindow(&dlgRect); //如果要显示对话框起始动态效果的话,不能使用该句 m_bVertical=false; //默认收缩对话框 } // --------------------------------------------------------- // 名称: OnMore // 功能: 是否允许显示 // 变量: 无 // 返回: 无 // 编写: 徐景周,2002.4.8 // --------------------------------------------------------- void CAbout::OnMore() { m_bVertical = !m_bVertical; if(m_bVertical == FALSE) //不显示 { SetDlgItemText(ID_MORE,_T("更多>>")); SizeWindow(m_nReducedHeight,true); // m_DyCredits.EndScrolling(); //停止滚动 } else //显示 { SetDlgItemText(ID_MORE,_T("<<隐藏")); SizeWindow(m_nReducedHeight,false); m_DyCredits.StartScrolling(); //开始滚动 } UpdateWindow(); } // --------------------------------------------------------- // 名称: SizeWindow // 功能: 伸展或收缩对话框 // 变量: ReduceHeight-收缩高度,bExtend-是否伸展 // 返回: 无 // 编写: 徐景周,2002.4.8 // --------------------------------------------------------- void CAbout::SizeWindow(int ReduceHeight, bool bExtend) { CRect rc; GetWindowRect(&rc); if(bExtend) { for (int i= 0; i < ReduceHeight; i++) { rc.bottom--; MoveWindow(&rc); } } else { for (int i= 0; i < ReduceHeight; i++) { rc.bottom++; MoveWindow(&rc); } } }
6. 如何让对话框回到屏幕中来
当对话框被拖离屏幕时,可用下面代码使其回到屏幕中。
SendMessage(DM_REPOSITION);
注:它必须是顶端窗口且不是child窗口。
7. 如何给对话框添加或去掉最大/最小化按钮
在OnCreate()或OnInitDialog() 改变其显示风格既可。
int CTest_deleteDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here SetWindowLong(this->m_hWnd,GWL_STYLE, GetWindowLong(this->m_hWnd,GWL_STYLE) | WS_MINIMIZEBOX | WS_MAXIMIZEBOX); return 0; }
或用:
ModifyStyle (NULL, WS_MAXIMIZEBOX);
8. 改变鼠标指针
可以在OnSetCursor中实现.
BOOL CTest_deleteDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default SetCursor(AfxGetApp()->LoadStandardCursor(IDC_UPARROW)); // Now we return instead of calling the base class return 0; // return CDialog::OnSetCursor(pWnd, nHitTest, message); }
9. 改变对话框的前景和背景色
可以在InitInstance()中实现。
//红色背景、绿色前景 SetDialogBkColor(RGB(255,0,0),RGB(0,255,0));
10. 在任务条上不显示图标
先从CWinApp继承类中建立一个不显示的顶级窗口.
CFrameWnd *abc=new CFrameWnd(); abc->Create(0,0,WS_OVERLAPPEDWINDOW); CNoTaskBarIconDlg dlg(abc); m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { } else if (nResponse == IDCANCEL) { } delete abc;
在 OnInitDialog中修改显示风格 WS_EX_APPWINDOW.
BOOL CNoTaskBarIconDlg::OnInitDialog() { CDialog::OnInitDialog(); ModifyStyleEx(WS_EX_APPWINDOW,0); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control }
11. 加入上、下文帮助
在 OnInitDialog 修改显示风格,加入上、下文HLP帮助显示.
BOOL HelpDialog::OnInitDialog() { ModifyStyleEx(0, WS_EX_CONTEXTHELP); return CDialog::OnInitDialog(); }
重载OnHelpInfo(...),用显示相关帮助信息
BOOL HelpDialog::OnHelpInfo(HELPINFO* pHelpInfo) { short state = GetKeyState (VK_F1); if (state < 0) // F1 key is down, get help for the dialog return CDialog::OnHelpInfo(pHelpInfo); else { // F1 key not down, get help for specific control if (pHelpInfo->dwContextId) WinHelp (pHelpInfo->dwContextId, HELP_CONTEXTPOPUP); return TRUE; } }
译者联系方式:
作者EMAIL:[email protected]
未来工作室(Future Studio)