下载sourcefiles–35Kb介绍你见过一个没有菜单项的菜单,或只是一个项目出现起来吗?例如在VC中创建的标准帮助菜单只有“关于”项。一些应用程序从非常基本的菜单面板。为什么
下载
source files – 35 Kb
介绍
你见过一个没有菜单项的菜单,或只是一个项目出现
起来吗?例如在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,所以我可以解决这些问题,在必要时一个偏移值。它是
没有实现的演示项目。
将菜单的代码非常简单(缓慢),最好的
解释只是读的:隐藏,收缩,复制Codevoid 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 {
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或隐藏,复制CodeAW_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/news10624.html