zoukankan      html  css  js  c++  java
  • 一些方便的对话框技巧,提示和解决方法

    介绍 这些是我在使用过程中发现的一些技巧 非对话框和基于对话框的应用程序中的对话框。的一些 可能看起来很幼稚,但却非常方便。我想我应该分享一些 技巧与你在一起时的感觉。 启动一个模态对话框隐藏 你经常听到人们抱怨,尽管在里面放了一个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

  • 相关阅读:
    委托学习小记(1)
    C# 对XML的 创建、查询
    C#多线程学习(六) 互斥对象
    C#多线程学习(二) 如何操纵一个线程
    C#多线程学习(四) 多线程的自动管理(线程池)
    16/11/22_plsql
    写日志
    内存检测
    开源
    vs2005 远程调试。
  • 原文地址:https://www.cnblogs.com/Dincat/p/13462212.html
Copyright © 2011-2022 走看看