介绍 这些是我在使用过程中发现的一些技巧 非对话框和基于对话框的应用程序中的对话框。的一些 可能看起来很幼稚,但却非常方便。我想我应该分享一些 技巧与你在一起时的感觉。 启动一个模态对话框隐藏 你经常听到人们抱怨,尽管在里面放了一个ShowWindow(SW_HIDE) 他们的OnInitDialog他们的模态对话框仍然在显示状态下启动。的 这里的问题是,当CDialog::OnInitDialog()完成时,它将调用 显示窗口(SW_SHOW)。这样,您的对话框再次可视。但是,就是这样 可以预料的是,人们已经开始解决这个问题了。这是你需要做的。 在对话框类中添加一个BOOL成员,并将其命名为可视。 现在在你的对话框构造函数设置可见为假。 隐藏,复制Code
visible = false;
现在你需要重写wm_windowposchange。你可能需要改变你的 在类向导中显示此消息的消息过滤选项。 隐藏,复制Code
void CTest_deleteDlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) { if(!visible) lpwndpos->flags &= ~SWP_SHOWWINDOW; CDialog::OnWindowPosChanging(lpwndpos); }
就是这样。现在你的模态对话框实际上以隐藏状态启动。和 如果你想让它可见,这就是你需要做的。 隐藏,复制Code
visible = true; ShowWindow(SW_SHOW);
全屏对话框 有时你可能觉得需要做一个全屏对话框-意味着 对话框,填充整个监视器。这很容易做到。 你需要删除标题和边框,这是通过删除隐藏来实现的。复制Code
WS_CAPTION
和WS_BORDER样式。然后我们叫隐藏用HWND_TOPMOST复制Code
SetWindowPos
并调整对话框大小以填充 整个屏幕。只需将以下代码放入OnInitDialog中 函数。 隐藏,收缩,复制Code
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); // Remove caption and border SetWindowLong(m_hWnd, GWL_STYLE, GetWindowLong(m_hWnd, GWL_STYLE) & (~(WS_CAPTION | WS_BORDER))); // Put window on top and expand it to fill screen ::SetWindowPos(m_hWnd, HWND_TOPMOST, -(GetSystemMetrics(SM_CXBORDER)+1), -(GetSystemMetrics(SM_CYBORDER)+1), cx+1,cy+1, SWP_NOZORDER); //... return TRUE; }
如何把注意力转移到2K/XP上 我敢打赌,有时你会怀念过去的日子,当一个简单的场景摆在窗前 让你的对话更有焦点。叹息!现在2K/XP有了一些改变 因此,如果您尝试一个简单的SetForegroundWindow,您最终会刷新 任务栏图标出现了几次(我从来没有数过,但有东西告诉我它在闪烁 三次)。这不是你想做的,对吧?幸运的是,我们有办法 您的对话框到前景。 技巧是使用AttachThreadInput附加以下线程 拥有当前线程的前台窗口,然后调用Hide复制Code
SetForegroundWindow
,然后分离附加的线程,再次使用 AttachThreadInput。酷,不是吗? 隐藏,复制Code
//Attach foreground window thread //to our thread AttachThreadInput( GetWindowThreadProcessId( ::GetForegroundWindow(),NULL), GetCurrentThreadId(),TRUE); //Do our stuff here ;-) SetForegroundWindow(); SetFocus(); //Just playing safe //Detach the attached thread AttachThreadInput( GetWindowThreadProcessId( ::GetForegroundWindow(),NULL), GetCurrentThreadId(),FALSE);
使你的对话保持在顶部 你没见过有“永远呆在顶部”选项的节目吗?好吧, 令人难以置信的是,你可以让你的对话框停留在顶端 行代码。只需在您的对话框类中放入以下代码行即可 OnInitDialog()函数。 隐藏,复制Code
SetWindowPos(&this->wndTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
基本上,我们所做的是使用SetWindowPos函数来更改 对话框的z顺序。我们让我们的对话保持在所有其他对话之上 将其移动到z顺序的顶部。即使你激活了一些 其他窗口,我们的窗口会在上面。但我建议你一定要确定 当你这样做的时候,要确切地知道你在做什么,因为如果你这样做的话,可能会惹恼别人 当他们想把你的窗户移开的时候,他们是无法做到的。 展开和收缩对话框 我敢打赌,你一定见过有对话框的程序,以一个大小开始。 它们会有一个按钮叫"展开视图"或者叫 “高级”,当你点击那个按钮时,对话框会漂亮地展开 揭示了一些迄今为止隐藏的儿童控件。它们也可能有一些按钮 叫做"隐藏细节",当你点击它,它会收缩回 原来更小的尺寸隐藏了额外的控件,在扩展时被揭示。 使用SetWindowPos可以很容易地实现这一点,正如您所看到的,这是一个相当好的方法 有用的函数。 假设你有两个按钮,“MakeSmall”和“Expand”。那么这就是 您需要放入它们的单击处理程序函数。当然,你需要更换 cx和cy参数与您自己的值。 隐藏,复制Code
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); }
还记得在你的对话框中调用OnMakeSmall() 函数的作用是:使您的对话框窗口在合同中开始 大小。相反,您可以通过调用OnExpand()来展开它 OnInitDialog()。有时你想使用相同的按钮,改变 按钮标题,并使用布尔标志来决定何时展开 以及何时签约。 顺便说一下,这是Thomas Freudenberg的另一个建议。这是 事实上,即使在收缩之后,隐藏的控制仍然是 可通过键盘访问,因此您可能想禁用这些控件使用 EnableWindow。我要感谢托马斯的建议: 你错过了一些关于“扩展和收缩你的对话”的内容 盒子”。似乎你更喜欢使用鼠标而不是键盘(你是一个 所谓的Mausschubser(德文的意思)老鼠《好色客》)如果一个对话框 简约,你仍然可以使用tab键去控制之外 的对话框。我建议叫EnableWindow (fExtracted)合适 控制。 让你的对话框到桌面 有时用户可能移动对话框屏幕直到部分 在桌面。你可能会想把回的对话框 完整的视图。还可能存在这样一种情况你的发展 更高的分辨率和在您的机器上是漂亮的和完整的,但最后 用户可能会使用屏幕分辨率较低,因此对话框的一部分 屏幕。再一次你真的想确保对话框 完全可见。信不信由你,这个可以只有一个来完成 行代码。 隐藏,复制Code
SendMessage(DM_REPOSITION);
顺利是吗?记住,这个消息只适用于高层对话框 和孩子对话框不会工作。 最小化、最大化按钮添加到对话框 如果你想做这个在设计时,所有你需要做的就是设置 相应的属性。但是如果因为某些原因你在运行时需要这样做 这是你需要做什么。覆盖OnCreate()和添加此代码。 请注意,把这段代码在OnInitDialog()有一个奇怪的副作用。 按钮会显示,最大化和最小化;但是他们是假的, 这意味着他们不正确的函数。我的猜测是,OnInitDialog () 晚一个地方改变对话框的风格。 隐藏,复制Code
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; }
还要注意比原始CREATESTRUCT lpCreateStruct只有一份 过去了。因此改变风格位没有影响。和一些令人费解的 (至少对我来说)原因,PreCreateWindow永远不会要求一个模态对话框 因此我们不能改变风格也,我们可能会做一个视图 窗口或框架窗口。 改变鼠标光标——从安德鲁和平 嗯,我想感谢安德鲁和平这个建议。有时你可能 觉得需要改变默认的鼠标光标在一个对话框。你需要做什么 覆盖OnSetCursor,设置一个新的光标没有调用然后返回 基类函数如下显示。我试过,因为我一直失败 调用基类。再次感谢安德鲁和平指向我 正确的方向。 隐藏,复制Code
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); }
改变对话框的背景和控制文本颜色 有一个问题经常CWinApp成员函数,SetDialogBkColor, 让我们做到这一点。这个函数接受两个colorref作为其参数。 第一个是对话框的背景色。也就是说第二 静态的颜色,检查和无线电控制。它不会影响编辑和 按钮控件。所有对话框和消息盒子里长大的 全球应用程序将使用这些颜色。把这段代码CWinApp 派生类的InitInstance()。记得要调用这个函数之前你 实例化CDialog-derived对象。 隐藏,复制Code
//Red background with Green colored controls SetDialogBkColor(RGB(255,0,0),RGB(0,255,0));
这个函数是现在过时了!它甚至可能不工作!我将更新本文 用正确的方法在未来的更新! 删除你的基于对话框的应用程序任务栏图标 有时候您可能想要创建隐形对话框应用程序等等 的原因。他们不会隐形自对话框将在适当的意义上 可见。但是让我们假设你不希望他们有任务栏图标等等 的原因。这是如何实现这一点。我们首先创建一个看不见的 水平框架窗口。这是代码放入CWinApp-derived 类只; 隐藏,复制Code
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;
现在我们需要修改对话框的风格。所以你把这段代码 CDialog-derived类的OnInitDialog。我们需要删除 WS_EX_APPWINDOW风格。 隐藏,复制Code
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 }
上下文敏感的帮助- P J阿伦兹 本文从皮特·阿伦兹向您展示如何获得上下文敏感的帮助你 对话框。你需要做的第一件事是确保对话框 有问号的标题栏。你需要这样做 OnInitDialog如下所示。 隐藏,复制Code
BOOL HelpDialog::OnInitDialog() { //blah blah blah //blah blah blah ModifyStyleEx(0, WS_EX_CONTEXTHELP); return CDialog::OnInitDialog(); }
OnHelpInfo(…)可以在两种不同的情况下被调用。第一个 当用户按下F1键。这通常应该打开 主要帮助窗口对话框。另一种情况是当用户点击 问号,然后点击单个控制对话框。 或者用户也可以右键点击“控制和选择 从弹出菜单?”选项。当然你必须处理出现的 自己的菜单。因此我们需要处理这两种情况如下所示。 隐藏,复制Code
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; } }
记住控制必须有一个帮助ID相关联的。这可以 通过采取[属性——General选项卡——帮助ID复选框)。当然 你还需要写他lp文件为您的程序。谢谢。 主对话框消失后显示消息框 有时,您需要显示某种类型的消息框 在基于对话框的应用程序中的主对话框被驳回后。但 您将注意到您的消息框从未显示。有趣的是,如果你放一个休息 在这里,程序在调试时确实会中断。这里的问题是, 在基于对话框的应用程序中,CWinThread::m_pMainWnd是 对话框本身,当对话框被解除时,主窗口是 被销毁,程序退出。解决方案是注释掉其中的行 m_pMainWnd被设置为对话框窗口。 隐藏,收缩,复制Code
BOOL CTestApp::InitInstance() { // .... CTestDlg dlg; /* Comment out the following line */ //m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle // when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle // when the dialog is // dismissed with Cancel } MessageBox(NULL,"Some message","Title",0); return FALSE; }
当然,你不能从你的任何地方调用AfxGetMainWnd 应用程序。因为AfxGetMainWnd盲目返回隐藏复制CWinApp派生类的Code
m_pMainWnd
成员。否则 你能做的是把你的CDialog*保存到一些其他成员 变量,说m_pMainWnd2然后写一个函数AfxGetMainWnd2 它简单地返回m_pMainWnd2,如果你想要使用 AfxGetMainWnd。 最后一次更新 由于我经常更新这篇文章,所以我没有维护一个完整的 历史,但我将在这里提到上次更新的信息。以下 在2002年9月18日的最新更新中增加了一个或多个提示。 全屏对话框如何窃取焦点2K/XP 本文转载于:http://www.diyabc.com/frontweb/news5039.html