欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
delphi 消息機制引入的一個(gè)副作用
 

Delphi 在處理進(jìn)程的消息時(shí)引入了一個(gè)隱藏的窗體Application ,借此進(jìn)行消息的分發(fā)。這樣的機制優(yōu)美的處理了消息的分發(fā)和處置的問(wèn)題。但是最近我發(fā)現這個(gè)機制也引入了一個(gè)副作用,會(huì )在某些情況下影響程序的界面交互行為。

我遇到的需求是需要在程序中實(shí)現單個(gè)實(shí)例,并且在第二個(gè)實(shí)例被啟動(dòng)的時(shí)候,首先將前一個(gè)實(shí)例置到最前,然后退出。按說(shuō)這樣的問(wèn)題應該是比較典型的例子,但是這樣的一個(gè)簡(jiǎn)單需求就受到了這個(gè)副作用的影響。

我的實(shí)現方式是這樣的:第二個(gè)實(shí)例啟動(dòng)的時(shí)候,對前一實(shí)例發(fā)一個(gè)消息,要求它將自己置前,然后退出。至于前一個(gè)實(shí)例的句柄怎么取得,可以用FindWindows ,也可以用命名的FileMapping ,總之,第一個(gè)窗體就這樣接到了將自己置前的命令。

怎么將這個(gè)窗體置到最前呢?眾所周知,SetForegroundWindow 并不能真正將一個(gè)窗體置到最前,相反的,為了禮貌起見(jiàn),它會(huì )讓這個(gè)指定的窗體在任務(wù)欄里面閃動(dòng),吸引用戶(hù)注意,但是它不會(huì )把這個(gè)窗體蓋在Z-Order 的頂端。很有教養,但是我不喜歡,因為這不是我想要的。

于是我使用了這樣一個(gè)方法將我要的窗體直接置到最前面:

    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 屬性,這樣就可以了。有點(diǎn)不夠禮貌,不過(guò)要是禮貌有用的話(huà),要警察做什么?

好了,前面說(shuō)的內容似乎和我們的標題沒(méi)太多關(guān)系,可是后面的麻煩都根源在這里。

我發(fā)現,當第一個(gè)實(shí)例被最小化時(shí),第二個(gè)實(shí)例將它喚醒,將它的主窗體置到最前,然后窗體的“最小化”按鈕失效了!這時(shí)窗體可以操作、可以最大化、可以關(guān)閉,卻再也不能最小化了!

這是一個(gè)很郁悶的問(wèn)題,一個(gè)不能最小化的窗體實(shí)在是很不友好的,我可以接受一個(gè)不禮貌的窗體,卻不愿意接受一個(gè)這樣不友好的家伙。

我發(fā)現問(wèn)題原因的過(guò)程是這樣的:

在進(jìn)程中,主窗體的WM_SYSCOMMAND 消息是被傳遞給Application 類(lèi)處理的,當CmdType 為SC_MINIMIZE的時(shí)候,Application 會(huì )調用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;

注意這個(gè)IsIconic(FHandle),它就是問(wèn)題原因的冰山一角。IsIconic 是用來(lái)檢測窗體是否處于最小化狀態(tài)的API。我發(fā)現,第二實(shí)例將前一實(shí)例的主窗體置前之后,這個(gè)窗體最小化調用這個(gè)方法時(shí),每次IsIconic(FHandle) 都是True。也就是說(shuō),Application 一直認為自己是最小化的。

于是問(wèn)題就比較清楚了:我們在將主窗體強行置到最前的時(shí)候,Application 并沒(méi)有恢復原狀態(tài)。于是在Minimize 方法中主窗體就得不到最小化的命令了。

難怪在VC 開(kāi)發(fā)的程序中不會(huì )有這樣的問(wèn)題!因為不存在A(yíng)pplication 的這個(gè)因素。

于是我們只要將主窗體強行置前之前,首先將Application 恢復:

if IsIconic(Application.Handle) then
begin
    DefWindowProc(Application.Handle, WM_SYSCOMMAND, SC_RESTORE, 0);
end;

這樣就好了。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Delphi7使用控件CoolTrayIcon時(shí)如何做到程序啟動(dòng)就最小化到托盤(pán)
delphi 常見(jiàn)問(wèn)題集錦
【轉】Delphi FireMonkey 結構性初略分析
使用ApplicationContext的類(lèi)完全封裝閃屏功能
倆個(gè)窗體之間出現 :" 未將對象引用到新的實(shí)例" 錯誤的情況
Delphi避免程序重復運行
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久