社区
C++ Builder
帖子详情
“高”技术
xiaohuilau
2001-03-07 11:26:00
1、请问各位如何制作像 WINDOWS 9x 一样的开始菜单,例如菜单的左边有张画。
2、如何判断当前焦点是否本窗口?我试,用 LostFocuse 不行!
...全文
284
16
打赏
收藏
“高”技术
1、请问各位如何制作像 WINDOWS 9x 一样的开始菜单,例如菜单的左边有张画。 2、如何判断当前焦点是否本窗口?我试,用 LostFocuse 不行!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
16 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
richardlong
2001-03-16
打赏
举报
回复
to suprer(不死鸟),能否也给我一个,Thanks!
longzaidi@sina.com
孩皮妞野
2001-03-13
打赏
举报
回复
Me2:)alng@elong.com
「已注销」
2001-03-13
打赏
举报
回复
秋枫一眼就看出来了顶楼的意思
可惜有几层竟然没体会到楼主是想画个"WINDOWS98"字样的图片而不是菜单图标
真有意思………这个我曾经做过 就是把一张图片和一个菜单同时出现同时消失 但效果并不理想
对于第二个问题我以前做《秋枫贴图1.0》的时候 为了实现程序的自动挂起 研究过这个
FORM自身带的ACTIVE很有意思 我当时在小辉的网站上问 我说ACTIVE为什么并不激活
可能很多人都以为我一定太菜了 实际上不亲身试验过的是不知道这其中有意思的地方的
它就是不激活
大家可到我的主页上下载《秋枫贴图》 http://yeqiufeng.51.net
我最初的想法是把鼠标往小窗口上一晃 就唤醒我的程序 结果我发现它就是唤不醒
万般无奈 我用了一个按钮来唤醒 我再一次感觉到WIDNOWS很幽默 有的时候
to:xiaohuilau
捕捉这个事件不应该访问FORM的ACTIVE 应该是APPLICATION的……
你下载我的那个程序用一用 那个程序是判断如果焦点不在了 就在一定的时间之后折叠起来
如果效果正如您所期望的话 我可给你源程序……
大家继续发表意见吧
xtzzll
2001-03-12
打赏
举报
回复
hi,给我一个吧,谢谢:)
XTZZLL@263.NET
xtzzll
2001-03-12
打赏
举报
回复
hi,给我一个吧,谢谢:)
sw0324
2001-03-12
打赏
举报
回复
to suprer(不死鸟):我也想要一个,可以吗?
sw0324@sohu.com
suprer
2001-03-12
打赏
举报
回复
有一个叫做CoolMenuPro的控件完全可以做出这样的效果,而且还可以做出OFFICE2000的那种可以隐藏的菜单,我对其进行了修改,需要的话和我联系suprer@sina.com。
xiaohuilau
2001-03-10
打赏
举报
回复
SORRY!应是焦点
孩皮妞野
2001-03-09
打赏
举报
回复
什么叫光标的失去?
孩皮妞野
2001-03-08
打赏
举报
回复
//Extraction
讯息使用范例一 使用者自定标题棒的实作
一般Windows程式的标题棒位於视窗的上方,我们可以利用该标题棒来移动视窗。以下我将为你示范如何利用C++Builder实作出置於视窗左方的标题棒。如图一:
图一 标题棒在左方的视窗。
如上图,你可以很清楚地看到,这个视窗和其他的视窗有很大的不同;它的标题棒位於左方,而且其颜色为绿色,同时其文字的走向为由下而上的90度字形,而其功能则和一般的标题棒相同,你可以将滑鼠移至该处,然後移动该视窗。到底这是如何达成的呢?
WM_NCHITTEST讯息的奥秘
WM_NCHITTEST讯息是一个很特殊的讯息。它是用来决定目前滑鼠所在位置属性的讯息,因此我们可以利用此特性,当滑鼠移至指定的位置时,传回 HTCAPTION,使得系统以为滑鼠目前位於标题棒,如此你就可以移动视窗了。如何?是不是很神奇呢?
由上可知,只要我们适时地拦截WM_NCHITTEST讯息,然後传回HTCAPTION,就可以顺利地欺骗系统,达成在任何位置模拟出标题棒的效果。
C++ Builder的处理讯息的巨集
在C++Builder为了处理讯息的方便,因此定义了叁个处理讯息的巨集(Macro)。
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_NCHITTEST,TMessage,OnNcHitTest)
END_MESSAGE_MAP(TForm)
以上的叁个巨集BEGIN_MESSAGE_MAP、MESSAGE_HANDLER及END_MESSAGE就是C++ Builder定义的巨集,其中比较重要的是MESSAGE_HANDLER;它共需要叁个参数,第一个参数代表讯息的ID,第二个代表参数型态,最後一个则是讯息事件处理函数。
乍看之下,这个巨集似乎和MFC及OWL所使用的巨集有几分神似,没错,不过其机制却更为简单及简洁,我们可以看看C++Builder对於这叁个巨集的原始定义:
#define BEGIN_MESSAGE_MAP virtual void __fastcall Dispatch(void *Message) \
{ \
switch (((PMessage)Message)->Msg) \
{
#define MESSAGE_HANDLER(msg,type,meth) \
case msg: \
meth(*((type *)Message)); \
break;
#define END_MESSAGE_MAP(base) default: \
base::Dispatch(Message); \
break; \
} \
}
相较於MFC或 OWL的可怕巨集,它实在是简单多了,这是因为C++Builder已替你完成了大部份的工作。其实若我们把以上的巨集展开後,可以得到以下的结果:
virtual void __fastcall Dispatch(void *Message)
{
switch (((PMessage)Message)->Msg)
{
case WM_NCHITTEST:
OnNcHitTest(*((TMessage *)Message));
break;
default:
TForm::Dispatch(Message);
break;
}
}
怎麽样?展开之後是不是有恍然大悟的感觉,要弄清楚这个巨集在卖啥膏药是很容易的,如果你玩过MFC的讯息处理机制,再看到以上的巨集,相较之下,实在是小儿科,不过也就因其简单,所以C++Builder的优势益加彰显。
我简单地说明以上的程式:在每个TForm中都定义一个名为Dispatch的虚拟函式,它就是用来处理Windows的讯息的,在大部份情况下,讯息都是呼叫C++Builder所提供的处理函式,因此你不需要修改它。
换句话说,我们只要改写Dispatch函式,就可以藉以处理指定的讯息了。前面提到的叁个巨集只是将这个程序简化而已,没什麽大不了。
自定标题的绘制
由於我们要使用自定的标题,所以你必须将程式所使用的 TForm的BorderStyle性质设为 bsNone,如此你的TForm就不会有标题棒了。
再来你就必须自行绘制标题棒,我们希望绘制一个位於左於的标题,因此我们必须处理TForm的OnPaint事件,然後在此事件中绘制标题棒。以下即为其事件处理函式:
void __fastcall TForm1::FormPaint(TObject *Sender)
{
RECT rc;
::SetRect(&rc,0,0,ClientWidth,ClientHeight);
DrawButtonFace(Canvas,rc,1);
Canvas->Pen->Color=clGreen;
Canvas->Brush->Color=clGreen;
Canvas->Rectangle(0,0,20,ClientHeight);
:// 以下略去
:
}
你可以看到,我们画出一个宽为20,颜色为绿色的标题棒。因此我们处理WM_NCHITTEST讯息的处理函式也必须做相对应的修改:
void __fastcall TForm1::OnNcHitTest(TMessage& Msg)
{
TPoint pt;
pt.x=LOWORD(Msg.LParam);
pt.y=HIWORD(Msg.LParam);
pt =ScreenToClient(pt);
RECT rc;
::SetRect(&rc,0,0,20,ClientHeight);
if (PtInRect(&rc,pt))
Msg.Result = HTCAPTION;
else
DefaultHandler(&Msg);
}
OnNcHitTest函式首先取得目前滑鼠所在点,注意,WM_NCHITTEST讯息所传入的点为相对於萤幕的绝对座标,因此在取得该点後必须利用ScreenToClient函数将它转为TForm的相对座标值,然後再据以判断是否落於我们所定义的标题棒范围内,若是则传回HTCAPTION值,否则就交由内定的处理函式DefaultHandler来处理。如此就完成了一个位於左方的标题棒了。
旋转文字的输出
仔细观察图一,你会发现它所使用的标题字元的方向,已经因应标题棒的转向而成为90旋转的文字,这是如何达成的呢?
其实说穿了没什麽,只是利用传统SDK的绘图方法来画出来的。因为在C++Builder的TFont物件并没有定义文字旋转的属性,所以我们只好透过传统的GDI绘图方法来达成这个目标。
char* msg=Caption.c_str();
LOGFONT fontRec;
memset(&fontRec,0,sizeof(LOGFONT));
fontRec.lfHeight = -13;
fontRec.lfWeight = FW_NORMAL;
fontRec.lfEscapement = 900; // 旋转文字的关键
lstrcpy(fontRec.lfFaceName,"细明体");
HFONT hFont=CreateFontIndirect(&fontRec);
HFONT hOld=::SelectObject(Canvas->Handle,hFont);
::SetRect(&rc,0,0,20,ClientHeight);
::SetTextColor(Canvas->Handle,RGB(255,255,255));
::TextOut(Canvas->Handle,3,ClientHeight-3,msg,lstrlen(msg));
::SelectObject(Canvas->Handle,hOld);
::DeleteObject(hFont);
以上的程式我不打算详加说明,简单地说,它就是建立一个旋转90度的字形,然後将字串以此字形画於萤幕上,此段程式码的关键在於你必须知道Canvas->Handle即是代表GDI绘图的HDC。其馀的函式说明你都可以在一般讲解传统Windows SDK绘图的书籍中找到。
由此我们也可以得到一个经验:虽然C++Builder的快速程式发展环境已经取代了传统SDK式的程式设计中大部份的工作,然而通晓一些必要的SDK程式技巧却可以使你上一层楼。所以我建议你在『行有馀力』时,不妨可以看看SDK相关书籍,充实基础知识。或许我们可以名之为『立足 BCB,放眼 SDK』的学习态度吧!
其他说明
在本程式中因为TForm的BorderStyle性质为bsNone。因此并没有外框,为了美化视窗,所以我写了几个辅助函式来绘出立体框。若你在其他程式中有类似的需求,也可以使用之。
void DoRect(TCanvas* Canvas,RECT& rect,COLORREF cTopColor,COLORREF cBottomColor)
{
POINT p[3];
p[0].x = rect.right;
p[0].y = rect.top;
p[1].x = rect.left;
p[1].y = rect.top;
p[2].x = rect.left;
p[2].y = rect.bottom;
Canvas->Pen->Color=TColor(cTopColor);
Canvas->Polyline(p,3);
p[1].x = rect.right;
p[1].y = rect.bottom;
p[2].x--;
Canvas->Pen->Color=TColor(cBottomColor);
Canvas->Polyline(p,3);
}
void Frame3D(TCanvas* Canvas,RECT& rect,COLORREF cTopColor,COLORREF cBottomColor,int iColWidth)
{
rect.bottom--; rect.right--;
while (iColWidth > 0)
{
iColWidth--;
DoRect(Canvas,rect,cTopColor,cBottomColor);
InflateRect(&rect,-1,-1);
}
rect.bottom++; rect.right++;
}
void DrawButtonFace(TCanvas* Canvas,RECT& rect,int nBevelWidth)
{
Canvas->Brush->Color=clBtnFace;
Canvas->FillRect(TRect(rect));
Frame3D(Canvas,rect,::GetSysColor(COLOR_BTNSHADOW),::GetSysColor(COLOR_WINDOWFRAME),nBevelWidth);
Frame3D(Canvas,rect,::GetSysColor(COLOR_BTNHIGHLIGHT),::GetSysColor(COLOR_BTNSHADOW),nBevelWidth);
}
这叁个函式中最重要的就是 DrawButtonFace,它是用来在一个矩形范围中画出一个类似Button的立体方框,在本程式中我用它来画出TForm的边框。你可以由图一看出它的视觉效果。
程式的改进
前面我们提到改进bsNone视窗视觉效果的方式是利用自行撰写的DrawButtonFace函式来达成,它虽不失为一个解决问题的方法,但是却也因此增加了程式的复杂度,再来我为你示范一种利用改写CreateParams函式的技巧来达成类似功能的方法。
CreateParams是一个虚拟函式,你可以经由它来修改windows的style,因为原先在C++Builder中所定义的Form是一个Dialog(交谈窗),而交谈窗的外形内定是有标题棒的,然而如果我们如前面的方法将外框设为bsNone 的话,那就必须自行画出假的视窗外框,否则看起来不好看。
但是在Windows系统中除了前面的Dialog式的视窗之外,还提供了另一种POPUP式的视窗,只不过在C++Builder并未提供该选项罢了。因此我们其实可以透过改写CreateParams的方式来产生WS_POPUP形式的视窗,如此一来我们就不必煞费周章地撰写画外框的函式了。它的程式其实很简单,只是将Params.Style的WS_DLGFRAME (代表使用Dialog外框),改成另一种WS_POPUP (弹出式视窗)。要做到以上效果,只要利用and及or运算就可以达到了。以下即为其程式码:
void __fastcall TForm1::CreateParams(TCreateParams& Params)
{
TForm::CreateParams(Params);
Params.Style |= WS_POPUP;
Params.Style ^= WS_DLGFRAME;
}
图二为改写後的程式执行结果,不仅程式简洁了许多,而且外观也较好看,那是因为我们在画标题棒时,不会像前面一样将外框盖住的缘故。
孩皮妞野
2001-03-08
打赏
举报
回复
1. <<创世纪的C++Builder>>上有一个例子,跟你要求的一样. 在wangxudong.yeah.net上可以Download.
2. if(Screen->ActiveForm==this){
ShowMessage("Ha, ha, I have the focus!");
}
我不懂电脑
2001-03-08
打赏
举报
回复
1.lbsxyk(小娃儿) 说了,不重复。
2.用GetFocus()获得焦点所在窗口句柄,再看是不是你的窗口句柄:Form1->Handle
Sunny_Yirui
2001-03-08
打赏
举报
回复
有一点:WINDOWS的开始菜单是一个PANLE的变体,可以自己编程实现它的功能!
用WIN API可以判断当前的焦点窗体!!
xiaohuilau
2001-03-08
打赏
举报
回复
1、Sorry, 我要制作是左边有“图片”的菜单,不是制作有“图标”的菜单。
2、lbsxyk(小娃儿) 说的并不能实现,请你试试当光标切换到桌面再由桌面返回到你的程序,事件并不发生。
3、ALNG(阿良) 请问你如何实现光标的失去?
lbsxyk
2001-03-08
打赏
举报
回复
1。用PopupMenu1菜单,再加一个ImageList1,将PopupMenu1的Images属性设为ImageList1最后修改每个菜单项的Imageindex属性,使菜单项对应ImageList1中的图标。
2.TForm有两个事件OnActivate,OnDeactivate,前者在同一程序中窗口得到焦点时发生,后者是窗口失去焦点时发生。你只需在该事件中加入你要执行的程序。
yhec
2001-03-08
打赏
举报
回复
!!!!!!!!
精通JavaScript(jQuery之父力作)『
高
清晰』.pdf
jQuery之父John Resig 力作,我看了。很好的东西,对朋友们学习框架Prototype、jQuery等,有启示迪人的作用!【推荐!】
Game Engine Architecture(游戏引擎架构).PDF
3D游戏引擎设计方面的最新最牛
技术
,国外大师无私奉献,新书啊新书,速度学习吸收。
SPRING攻略 第2版.pdf
随着Spring框架最新版本——3.0版的发布,Spring平台已经发展成熟,成为Java、Java虚拟机、Groovy、NET或者Action-Script开发人员最强大、最具革命性的解决方案之一。 《Spring攻略(第2版)》是Spring平台的深入指南,它引导你进入Spring 3及其辅助框架的最新
技术
。《Spring攻略(第2版)》不仅为你全面而又深入地讲解各种概念,并且在每一章中都配备了一系列详细的代码示例,以帮助读者在实际的工作中迅速应用于实战。 SpringSource为核心框架添加了许多部件。这些部件不仅简化了Java EE之上的API,并且为Java EE所忽略的问题提供了第一流的完整解决方案。构建于Spring IoC容器组件模型之上的这些Spring3部件提供了集成、批处理、OSGi、Ajax和Flex集成、状态式的Web应用、REST风格Web服务、富客户端用户界面、Google AppEngine开发、基于云的部署、消息、数据访问、Web服务等多种功能。而且,Spring能很好地与其他辅助框架(包括业务过程管理、群集缓冲以及网格计算)进行协作。 你在寻求和Ruby on Rails一样的一体化架构吗?那么你会被Grails等Spring替代方案所深深吸引,对于Groovy开发人员来说,Grails具有难以置信的能力和生产率。如果你是寻求快速、轻量级的应用构建方法的Java开发人员,你会喜欢上Spring Roo,它能让你快速地通过应用的原型阶段,进入维护阶段,形成清晰的、面向最佳实践的代码。 以上所有这些主题,在这本以丰富代码为基础的攻略中都能找到。我们希望你能够享受Spring平台的学习和使用。 Gary Mak,Josh Long和Daniel Rubio。 作者简介 作者:(美国)麦克(Gary Mak) (美国)隆(Josh Long) (美国)卢比奥(Daniel Rubio) 译者:陈宗恒 姚军 蒋亮 麦克,Gary Mak,Meta-Archit软件
技术
有限公司的创立者及首席顾问。 隆,Josh Long,SpringSource的Spring开发倡导人。 卢比奥,Daniel Rubio,超过10年的企业级和Web开发经验顾问。
网络
技术
资料大全
超长篇,
技术
资料大全, 总结的非常好!值得一看!
下载 多线程编程
技术
开发资料
高
清完整PDF版
多线程编程
技术
开发资料.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
C++ Builder
13,874
社区成员
102,696
社区内容
发帖
与我相关
我的任务
C++ Builder
C++ Builder相关内容讨论区
复制链接
扫一扫
分享
社区描述
C++ Builder相关内容讨论区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章