动画对话框菜单与客户的阴影

介绍 你见过一个没有菜单项的菜单,或只是一个项目出现 起来吗?例如在VC中创建的标准帮助菜单只有“关于”项。 一些应用程序从非常基本的菜单面板。为什么不显示对话框呢 后面一个菜单项的菜单项。有我来 这个新主意! 它是如何工作的 使动画对话框菜单真正简单的Windows 98, NT5之后, 旧系统的解决方案要复杂的多。这是 第一个版本的代码,肯定有很多“bug”。我希望它是有用的 一个人。 关键是深深隐藏在AnimateWindow函数 Windows API。一个好主意在使用windows API函数是“初步” 加上这两条线在任何标题得到包含在应用程序代码: 隐藏,复制Code

#undef     WINVER
#define     WINVER 1000000

嘿,不是一个好主意,但Visual c++ 6的唯一选择 一些服务包和Windows XP专业版SP1(是的,它是!)。你应该 首先检查调用AnimateWindow工作没有它。 WINVER是VC定义为了识别的windows版本 正在建设。这是预定义的和API声明引用时 一些兼容性信息是必需的。编译时你将得到什么 如果你想要一个稳定的构建。 我创建了一个基于对话框的应用程序,包含一个子对话框 作为一个菜单栏(即CDummy)。菜单栏的对话框 处理用户请求通过弹出对话框。它也画的影响 和大多数的清理/重画操作。简单的按钮控制弹出 操作。我以前的一个小技巧是连续的IDs按钮 1026、1027、1028,所以我可以解决这些问题,在必要时一个偏移值。它是 没有实现的演示项目。 将菜单的代码非常简单(缓慢),最好的 解释只是读的:隐藏,收缩,复制Code

void CDummy::ShowDialogMenu(int number, int initial_control)
{
    HideAllDialogMenus();
    if(!statMenu[number])
    {
        CRect rc;
        GetDlgItem(initial_control)->GetClientRect(&rc);
        GetDlgItem(initial_control)->ClientToScreen(&rc);
        this->ScreenToClient(&rc);

        listMenu[number]->SetWindowPos(0,rc.left,rc.bottom,
                    0,0,SWP_NOSIZE|SWP_HIDEWINDOW);
        AnimateWindow(listMenu[number]->GetSafeHwnd(),300,
            AW_ACTIVATE|AW_SLIDE|AW_VER_POSITIVE|AW_HOR_POSITIVE);
        CWindowDC dc(0);
        CDC tdc;
        statMenu[number]=1;
        listMenu[number]->GetClientRect(&rc);
        listMenu[number]->ClientToScreen(&rc);
        dc.MoveTo(rc.left,rc.top);
        dc.LineTo(rc.right,rc.top);
        dc.LineTo(rc.right,rc.bottom);
        dc.LineTo(rc.left,rc.bottom);
        dc.LineTo(rc.left,rc.top);

        tdc.CreateCompatibleDC(&dc);
        CBitmap map1;
        map1.CreateCompatibleBitmap(&dc,1600,1200);
        tdc.SelectObject(&map1);
        tdc.BitBlt(rc.left,rc.top,rc.right+S_SHADE,
                    rc.bottom+S_SHADE,&dc,rc.left,rc.top,SRCCOPY);

        for(int w=rc.right;w<=rc.right+S_SHADE;w++)
        {
            float f=((float)w-rc.right)/S_SHADE;
            for(int e=rc.top+S_SHADE;e< rc.bottom;e++)
            {
                tdc.SetPixel(w,e,RGB(
                    GetRValue(tdc.GetPixel(w,e))/(2-f),
                    GetGValue(tdc.GetPixel(w,e))/(2-f),
                    GetBValue(tdc.GetPixel(w,e))/(2-f)));
            }
        }
        for(int e=rc.bottom;e<=rc.bottom+S_SHADE;e++)
        {
            float f=((float)e-rc.bottom)/S_SHADE;
            for(w=rc.left+S_SHADE;w<=rc.right+1;w++)
            {
                tdc.SetPixel(w,e,RGB(
                GetRValue(tdc.GetPixel(w,e))/(2-f),
                GetGValue(tdc.GetPixel(w,e))/(2-f),
                GetBValue(tdc.GetPixel(w,e))/(2-f)));
            }
        }
        for(e=rc.bottom;e<=rc.bottom+S_SHADE-2;e++)
        {
            float f=((float)e-rc.bottom)/S_SHADE;
            for(w=rc.right+2;w<=rc.right+S_SHADE-2;w++)
            {
                float g=((float)w-rc.right+2)/(S_SHADE);
                tdc.SetPixel(w,e,RGB(
                    GetRValue(tdc.GetPixel(w,e))/(2-(f+g)/2),
                    GetGValue(tdc.GetPixel(w,e))/(2-(f+g)/2),
                    GetBValue(tdc.GetPixel(w,e))/(2-(f+g)/2)));
            }
        }

        dc.BitBlt(rc.left,rc.top,rc.right+S_SHADE,rc.bottom+S_SHADE,
                    &tdc,rc.left,rc.top,SRCCOPY);
    }
}

影子是完全的机制,它描绘直接在桌面上 窗口。这将导致一些问题清理油漆工作,但是很好 阴影。我将很快更新弹出窗口,然后将一些意义。 然而,如果您关心效率或涂料安全你可以做 CClientDC油漆。隐藏菜单程序只是一个重画。 必须说的是,你可以改变的动画类型 修改AnimateWindow的旗帜。例如改变 AW_ACTIVATE | AW_SLIDE | AW_VER_POSITIVE | AW_HOR_POSITIVE AW_ACTIVATE | AW_SLIDE | AW_HOR_POSITIVE或隐藏,复制Code

AW_ACTIVATE | 
AW_SLIDE | AW_VER_POSITIVE

或别的定义在MSDN AnimateWindow。 使用你的应用程序中的代码 我没有试图让一个类来实现功能,因为我想要的 用户控件的对话框的方式自定义。我的建议持开放态度。 不管怎样我设法单独以下步骤,应该使用 代码在您的应用程序更容易: 创建所有对话框要显示为菜单。推荐使用 CDialog继承了对话框。在属性选择的孩子,检查 控制、可见和前景。如果你不指定任何的风格 菜单可能不正确的油漆。他们都有与z值 家长管理,不知道如何。你知道在哪里挖细节,做的事 你不是。嘿,别忘了包括适当的头在你的隐藏,复制CodeCDummy源文件,所以你可以创建实例。 创建一个菜单栏对话框,就像CDummy。这个是遗传的 从CDialog,但它可以是任何CWnd基础的事情。 对于SDK的球迷,你可以使用直接处理轻微的修改 消除MFC设备上下文。在你的主窗口类声明一个实例 CDummy和初始化它(在OnInitDialog () 例子)如下:隐藏,复制Codedummy = new CDummy(这个); 假→创建(IDD_DIALOG2,); 假→SetWindowPos (0, 0, 0, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); 声明数组来存储指针指向你的对话框和当前状态 (演示项目:listMenu和statMenu)。创建的实例 你的菜单对话框,把初始化代码隐藏,复制CodeWM_INITDIALOG处理程序,像这样:隐藏,复制CodeBOOL CDummy: OnInitDialog () { CDialog: OnInitDialog (); memset (listMenu 0 sizeof (listMenu)); menu1.Create (IDD_DIALOG1,这→GetParent ()); menu1.SetWindowPos (0, -1000, -1000, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); menu2.Create (IDD_DIALOG3,这→GetParent ()); menu2.SetWindowPos (0, -1000, -1000, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); menu3.Create (IDD_DIALOG4,这→GetParent ()); menu3.SetWindowPos (0, -1000, -1000, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); menu4.Create (IDD_DIALOG5,这→GetParent ()); menu4.SetWindowPos (0, -1000, -1000, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); listMenu [0] =, menu1; listMenu [1] =, menu2; listMenu [2] =, menu3; listMenu[3] =和菜单4; 返回TRUE;//返回TRUE,除非您将焦点设置为控件 //异常:OCX属性页应该返回FALSE } 导致菜单显示或隐藏的事件必须发生在 CDummy。放一些按钮或其他东西,然后处理事件。在 演示项目我使用简单的按钮。这是我如何处理我的一个按钮 BN_CLICKED消息:Hide  复制代码void CDummy::OnButton1() { ShowDialogMenu (0, IDC_BUTTON1); }ShowDialogMenu(int arg1,int arg2)显示对话框 屏幕上。例如,arg1说明应该显示哪个对话框 表示将显示列表菜单[0]所引用的对话框。 arg2是控件(静态、按钮、编辑框、复选框、 无论什么)旁边的对话框将被绘制。函数获取客户端 控件的矩形,并在下面绘制对话框 矩形。 处理WM_KILLFOCUS在主窗口,原因之一,所有 菜单对话框必须是子对话框:CDmenuDlg::OnKillFocus(CWnd* pNewWnd) { CDialog: OnKillFocus (pNewWnd); 假→HideAllDialogMenus (); } 处理WM_ACTIVATE在主窗口,这种修复 “失焦后重画”,但不总是这样(见下文):隐藏OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { CDialog:: OnActivate (nState、pWndOther bMinimized); 假→HideAllDialogMenus (); 无效(); } 已知的问题 在Visual c++或我的代码中很少有错误。 有时AnimateWindow不做任何事情而返回 ERROR_SUCCESS。演示项目应用程序不会这样做,但是 您的应用程序可能没有这么幸运。我没能找出原因 这个问题,但是它适用于所有的初始函数。 单击主窗口中的控件不会使菜单消失 并在上面绘制控件。要修复此问题,可以使用消息反射或 手动将消息转发到主窗口,但您必须对所有操作都这样做 控件在主窗口上。我正在研究另一种解决方案。 如果菜单是活动的,而应用程序失去焦点,不正确的重绘将会 发生。最后一个对我来说是个谜! 在windows98和我的并行任务不能很好地一起工作,我 意味着它们运行缓慢,因为操作系统线程很弱。不要超载的应用程序 同时许多活动线程。 我被五角大楼雇佣来做这个项目。他们需要一些软件 附加到控制接口。你看,我没有包括司机,但是我 可能是意外地删除/留下了其他一些代码。让你的眼睛 打开!嘿,开玩笑的,但你要睁大眼睛,我可能忘了 提到一些小技巧,你需要使它工作。这是个好地方 再加上一句“如果这段代码能工作,它是弗拉基米尔·拉列夫写的,我不知道是谁。 写的!,就像一个为MSDN写文章的人。感谢您的评论 和修复。 学分 作者Vladimir Ralev <v_ralev@yahoo.com> 2003年10月20日 特别感谢PJ n笑容为他的伟大工作 CTreeFileCtrl,CSortedArray v1.06。我用( 说明一个人是如何容易地选择一个 文件,而不必弹出一个模态对话框。 本文转载于:http://www.diyabc.com/frontweb/news8586.html

原文地址:https://www.cnblogs.com/Dincat/p/13468251.html