| 订阅 | 在线投稿
分享
 
 
 

Delphi 消息机制引入的一个副作用

2007-02-07 12:19:07 编辑來源:互联网 国际版 评论
 
 
本文为【Delphi 消息机制引入的一个副作用】的汉字拼音对照版显示拼音
  Delphi zaichulijinchengdexiaoxishiyinruleyigeyincangdechuangtiApplication jiecijinxingxiaoxidefenfazheyangdejizhiyoumeidechulilexiaoxidefenfahechuzhidewentidanshizuijinwofaxianzhegejizhiyeyinruleyigefuzuoyonghuizaimouxieqingkuangxiayingxiangchengxudejiemianjiaohuxingwei

  woyudaodexuqiushixuyaozaichengxuzhongshixiandangeshilibingqiezaidiergeshilibeiqidongdeshihoushouxianjiangqianyigeshilizhidaozuiqianranhou退tuichuanshuozheyangdewentiyinggaishibijiaodianxingdelizidanshizheyangdeyigejiandanxuqiujiushoudaolezhegefuzuoyongdeyingxiang

  wodeshixianfangshishizheyangdediergeshiliqidongdeshihouduiqianyishilifayigexiaoxiyaoqiutajiangzijizhiqianranhou退tuichuzhiyuqianyigeshilidejubingzenmequdekeyiyongFindWindows yekeyiyongmingmingdeFileMapping zongzhidiyigechuangtijiuzheyangjiedaolejiangzijizhiqiandemingling

  zenmejiangzhegechuangtizhidaozuiqiannezhongsuozhouzhiSetForegroundWindow bingbunengzhenzhengjiangyigechuangtizhidaozuiqianxiangfandeweilelimaoqijiantahuirangzhegezhidingdechuangtizairenwulanlimianshandongxiyinyonghuzhuyidanshitabuhuibazhegechuangtigaizaiZ-Order dedingduanhenyoujiaoyangdanshiwobuxihuanyinweizhebushiwoxiangyaode

  yushiwo使shiyonglezheyangyigefangfajiangwoyaodechuangtizhijiezhidaozuiqianmian

   SetWindowPos(hForm, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);

   SetWindowPos(hForm, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);

  qiangxingbachuangtituodaoZ-Order dedingduanranhouqudiaotadeTOPMOST shuxingzheyangjiukeyileyoudianbugoulimaobuguoyaoshilimaoyouyongdehuayaojingchazuoshenme

  haoleqianmianshuodeneirongsihuhewomendebiaotimeitaiduoguanxikeshihoumiandemafandougenyuanzaizheli

  wofaxiandangdiyigeshilibeizuixiaohuashidiergeshilijiangtahuanxingjiangtadezhuchuangtizhidaozuiqianranhouchuangtide“zuixiaohua”anniushixiaolezheshichuangtikeyicaozuokeyizuidahuakeyiguanbiquezaiyebunengzuixiaohuale

  zheshiyigehenyumendewentiyigebunengzuixiaohuadechuangtishizaishihenbuyouhaodewokeyijieshouyigebulimaodechuangtiquebuyuanyijieshouyigezheyangbuyouhaodejiahuo

  wofaxianwentiyuanyindeguochengshizheyangde

  zaijinchengzhongzhuchuangtideWM_SYSCOMMAND xiaoxishibeichuandigeiApplication leichulidedangCmdType weiSC_MINIMIZEdeshihouApplication huitiaoyongMinimize fangfa

  procedure TApplication.Minimize;

  begin

   if not IsIconic(FHandle) then

   begin

   NormalizeTopMosts;

   SetActiveWindow(FHandle);

   if (MainForm <> nil) and (ShowMainForm or MainForm.Visible)

   and IsWindowEnabled(MainForm.Handle) then

   begin

   SetWindowPos(FHandle, MainForm.Handle, MainForm.Left, MainForm.Top,

   MainForm.Width, 0, SWP_SHOWWINDOW);

   DefWindowProc(FHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0);

   end else

   ShowWinNoAnimate(FHandle, SW_MINIMIZE);

   if Assigned(FOnMinimize) then FOnMinimize(Self);

   end;

  end;

  zhuyizhegeIsIconic(FHandle)tajiushiwentiyuanyindebingshanyijiaoIsIconic shiyonglaijiancechuangtishifouchuyuzuixiaohuazhuangtaideAPIwofaxiandiershilijiangqianyishilidezhuchuangtizhiqianzhihouzhegechuangtizuixiaohuatiaoyongzhegefangfashimeiciIsIconic(FHandle) doushiTrueyejiushishuoApplication yizhirenweizijishizuixiaohuade

  yushiwentijiubijiaoqingchulewomenzaijiangzhuchuangtiqiangxingzhidaozuiqiandeshihouApplication bingmeiyouhuifuyuanzhuangtaiyushizaiMinimize fangfazhongzhuchuangtijiudebudaozuixiaohuademinglingle

  nanguaizaiVC kaifadechengxuzhongbuhuiyouzheyangdewentiyinweibucunzaiApplication dezhegeyinsu

  yushiwomenzhiyaojiangzhuchuangtiqiangxingzhiqianzhiqianshouxianjiangApplication huifu

  if IsIconic(Application.Handle) then

  begin

   DefWindowProc(Application.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);

  end;

  zheyangjiuhaole原文
 
 
Delphi 在处理进程的消息时引入了一个隐藏的窗体Application ,借此进行消息的分发。这样的机制优美的处理了消息的分发和处置的问题。但是最近我发现这个机制也引入了一个副作用,会在某些情况下影响程序的界面交互行为。 我遇到的需求是需要在程序中实现单个实例,并且在第二个实例被启动的时候,首先将前一个实例置到最前,然后退出。按说这样的问题应该是比较典型的例子,但是这样的一个简单需求就受到了这个副作用的影响。 我的实现方式是这样的:第二个实例启动的时候,对前一实例发一个消息,要求它将自己置前,然后退出。至于前一个实例的句柄怎么取得,可以用FindWindows ,也可以用命名的FileMapping ,总之,第一个窗体就这样接到了将自己置前的命令。 怎么将这个窗体置到最前呢?众所周知,SetForegroundWindow 并不能真正将一个窗体置到最前,相反的,为了礼貌起见,它会让这个指定的窗体在任务栏里面闪动,吸引用户注意,但是它不会把这个窗体盖在Z-Order 的顶端。很有教养,但是我不喜欢,因为这不是我想要的。 于是我使用了这样一个方法将我要的窗体直接置到最前面: SetWindowPos(hForm, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE); SetWindowPos(hForm, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE); 强行把窗体拖到Z-Order 的顶端,然后去掉它的TOPMOST 属性,这样就可以了。有点不够礼貌,不过要是礼貌有用的话,要警察做什么? 好了,前面说的内容似乎和我们的标题没太多关系,可是后面的麻烦都根源在这里。 我发现,当第一个实例被最小化时,第二个实例将它唤醒,将它的主窗体置到最前,然后窗体的“最小化”按钮失效了!这时窗体可以操作、可以最大化、可以关闭,却再也不能最小化了! 这是一个很郁闷的问题,一个不能最小化的窗体实在是很不友好的,我可以接受一个不礼貌的窗体,却不愿意接受一个这样不友好的家伙。 我发现问题原因的过程是这样的: 在进程中,主窗体的WM_SYSCOMMAND 消息是被传递给Application 类处理的,当CmdType 为SC_MINIMIZE的时候,Application 会调用Minimize 方法: procedure TApplication.Minimize; begin if not IsIconic(FHandle) then begin NormalizeTopMosts; SetActiveWindow(FHandle); if (MainForm <> nil) and (ShowMainForm or MainForm.Visible) and IsWindowEnabled(MainForm.Handle) then begin SetWindowPos(FHandle, MainForm.Handle, MainForm.Left, MainForm.Top, MainForm.Width, 0, SWP_SHOWWINDOW); DefWindowProc(FHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0); end else ShowWinNoAnimate(FHandle, SW_MINIMIZE); if Assigned(FOnMinimize) then FOnMinimize(Self); end; end; 注意这个IsIconic(FHandle),它就是问题原因的冰山一角。IsIconic 是用来检测窗体是否处于最小化状态的API。我发现,第二实例将前一实例的主窗体置前之后,这个窗体最小化调用这个方法时,每次IsIconic(FHandle) 都是True。也就是说,Application 一直认为自己是最小化的。 于是问题就比较清楚了:我们在将主窗体强行置到最前的时候,Application 并没有恢复原状态。于是在Minimize 方法中主窗体就得不到最小化的命令了。 难怪在VC 开发的程序中不会有这样的问题!因为不存在Application 的这个因素。 于是我们只要将主窗体强行置前之前,首先将Application 恢复: if IsIconic(Application.Handle) then begin DefWindowProc(Application.Handle, WM_SYSCOMMAND, SC_RESTORE, 0); end; 这样就好了。
󰈣󰈤
日版宠物情人插曲《Winding Road》歌词

日版宠物情人2017的插曲,很带节奏感,日语的,女生唱的。 最后听见是在第8集的时候女主手割伤了,然后男主用嘴帮她吸了一下,插曲就出来了。 歌手:Def...

兄弟共妻,我成了他们夜里的美食

老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...

网络安全治理:国家安全保障的主要方向是打击犯罪,而不是处置和惩罚受害者

来源:中国青年报 新的攻击方法不断涌现,黑客几乎永远占据网络攻击的上风,我们不可能通过技术手段杜绝网络攻击。国家安全保障的主要方向是打击犯罪,而不是处置和惩罚...

 
 
 
>>返回首页<<
 为你推荐
 
 
 
 转载本文
 UBB代码 HTML代码
复制到剪贴板...
 
 
 热帖排行
 
游乐场的可爱性感(3)
游乐场的可爱性感(2)
玛旁雍错之景
华亿农庄
 
 
王朝网络微信公众号
微信扫码关注本站公众号wangchaonetcn
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
©2005- 王朝网络 版权所有