<object id="ged8u"></object>
  • <dd id="ged8u"><noscript id="ged8u"></noscript></dd><rp id="ged8u"></rp>
  • <tbody id="ged8u"><noscript id="ged8u"></noscript></tbody>

    新疆軟件開發

    本站首頁 軟件開發 成功案例 公司新聞 公司簡介 客服中心 軟件技術 網站建設
      您現在的位置: 新疆二域軟件開發公司 >> 開發語言 >> 文章正文

    在桌面中嵌入窗體

    前幾天在網上看到一個軟件的介紹:可以嵌入桌面,即使是“顯示桌面”也不會影響此程序?醋髡哒f的好像有多么的神奇一樣。周未就回來試一下。最后發現,Windows這個桌面還真是復雜和有意思。
      首先要分析Windows桌面。
      打開老牌軟件"Spy Window"。查看一下桌面。取得一個“SysListView32”類的句柄(本系統為XP版本)。將其最小化,可以看出剛才取得的控件好像是透明的。因為將其最小化之后,還可以看到你所設置的桌面圖片。
      重新用"Spy Window"獲取桌面上的控件句柄(也可以直接點擊"Parent Window"取得其父窗口句柄),得到一個"SHELLDLL_DefView"類的句柄。將其最小化,可以看到桌面圖片依然存在,難道又是一個透明控件嗎?先不理會它,我們繼續向“下”找。再一次取得“桌面”上一個類名為“Progman”的控件句柄。而且此時你會發現Spy Window的"Parent Window"按鈕已不可用了。
      這個類為“Progman”的窗口“下面”真的沒有其它窗口了嗎?按“Ctrl+Alt+Del“在任務管理器里結束“explorer”,后再使用“Spy Window”看一下,是不是又有一個類名為“#32769”的窗口出了。試著對此窗口進行禁用,最小化,隱藏操作試一下。好像一切都是無效的。
      到此為至,應該說把這張桌面的結構搞清楚了。相當于圖像處理中的四個圖層,而且是透明圖層。
      按類名由前至里的排序為:
      SysListView32
      SHELLDLL_DefView
      Progman
      #32769
      看來這個桌面果然不是一般的復雜。
      回憶一下以前用代碼來隱藏桌面的操作:
      FindWindow(''''Progman'''',Nil);
      ShowWindow(...);
      這里的''''Progman''''就是第三層(本文中我們就以層來稱呼它們)的窗口了。在結束進程“Explorer”時,此窗口消失,說明此窗口是由“Explorer.exe”建立的。
      下面進行將程序嵌入到桌面里的操作。
      這里所需要的只有一個語句:
      FrmMain.ParentWindow:=ParentHandle;其中,ParentHandle是你所要嵌人的控件句柄。
      按此實現,可以建立一個窗體,拖入一個TButton,一個TEdit。在Button的Click事件中寫入代碼FrmMain.ParentWindow:=StrToInt(EdtHandle.Text);
      下面,先來嵌入“第一層桌面”看一下。用"Spy Window”取得當前桌面句柄,也就是第一層''''SysListView32''''。轉為十進制后復制到EdtHandle。點擊按鈕。
      程序是不是轉為非焦點狀態了。按一下“Win+D”(顯示桌面)。是不是窗口仍停留在桌面上。
      好像文章開頭的目的已經實現了。
      仔細測試一下當前的窗體,是不是與原來有很大的不同。首先,窗口的標題欄總是非焦點狀態。第二窗體上的右擊被桌面攔截了下來。
      第三Edit里表顯不出TEdit本身對消息的響應。如點擊時,拖動時,按鍵時右擊時,Edit缺少相應的閃爍輸入光標,抹黑所選字符,文字處理,顯示上下文菜單等。這是因為窗體得不到焦點,而得不到焦點對于TEdit控件來說,一切都是無效的。
      動態取得第一層控件句柄的方法是:
      TmpHandle:=FindWindow(''''Progman'''',Nil);
      TmpHandle:=GetWindow(TmpHandle,GW_CHILD);
      TmpHandle:=GetWindow(TmpHandle,GW_CHILD);
      此時TmpHandle即是桌面的句柄了。
      依照此方法,我們可以將窗體嵌入第二層''''SHELLDLL_DefView''''了。當嵌入第二層時,你會發現。所嵌入的程序窗口不見了。當我們把第一層最小化時,可以看到我們所嵌入的窗口是存在的。只是被第一層所遮住了。所以說,第一層并不是透明的!
      第一層最小化之后,可以看到,桌面上的圖標都不見了。再看一下第一層的類名“SysListView32”,可以確定,第一層這個控件的作用主要就是列出系統桌面上的圖標。我們在當前第二層中點擊一下右鍵。桌面菜單出來了吧?原來一切的消息及處理都是在這一層接收和處理的。這時可以用“新建”命令新建一個文檔,之后再恢復第一層桌面,可以看到,新建的文檔出現了。
      可以這樣理解,第一層是“顯示層”,第二層是“功能層”。我們的窗體在這里是顯示不出來的。而且同樣得不到焦點。
      現在,將我們的程序嵌入到第三層''''Progman'''',嵌入之后,出現了和第二層相同的結果,按功能來說這一層應該沒有什么實際的用途,可能只是給上面兩層提供一個容器,F在''''Progman''''中有了兩個窗體,一個是原有的''''SHELLDLL_DefView'''',另一個便是這個嵌入窗體。但是前者用盡了所有的可視區域,所以才使得嵌入的窗體顯示不出來。這種情況似乎平時也會遇到,那我們在嵌入時加入一句:BringWindowToTop(FrmMain.Handle);試試;
      呵呵,看到了什么?是不是嵌入的窗口出現了?按一下"Win+D"看一下。如何?還在吧?如果桌面上有圖標的話,此時這個窗體應該是擋遮住了一部分圖標的。
    處理的辦法就是將上一層窗體縮小。如:
      TmpHandle:=FindWindow(''''Progman'''',Nil);
      TmpHandle:=GetWindow(TmpHandle,GW_CHILD);
      MoveWindow(TmpHandle,0,20,1024,740,False);
      這樣,在窗體頂部留出了二十象素的高度?梢苑乓粋任務欄式的窗體了。
      現在只剩下最后一層"#32769"了。只要在系統登陸前的啟動程序不變,此窗口的句柄應該是不變化的(有可能系統登陸前啟動的程序有變化此句柄也不變,具體情況沒試過)。
      按前面的方法將窗體嵌入到此窗口中。
      窗體又是得不到焦點的狀態了?梢钥闯鰜磉@和嵌入到第一層差不多。但是我們拖動一下窗體看一下。此時窗體并不是實時跟隨鼠標的。再仔細看一下,任務欄上出現了兩個此程序的按鈕。一個是程序的名稱,一個是窗口的名稱。這是一種奇怪的現象,從來沒有見過的;蛟S我們可以這樣解釋它。Explorer會將符合要求的窗體顯示在任務欄上(非ToolsWindows,并且可見)。本窗體就符合,而且Explorer又會將窗口"#32769"里的所有窗口放到任務欄上而不管它是否復。所以才會得到此結果。
      總結一下:
      Windows的桌面是分四層的。嵌入的窗體如果嵌入到第三層,并將Z軸順序移到最上的話,程序就會一個正常的嵌入桌面的程序。這符合我們的要求。而且可以通過調整第二層的大小來使窗體不遮住桌面圖標。所以,將窗體嵌入到此是很理想的。
      第一層的嵌入也是可以的。但是在這里窗體會得不到焦點和使用不了右鍵。所以這里的窗體受很多限制。
      第二層是一個根本不考慮嵌入窗體的地方,因為這里的窗體根本顯示不出來。而且與第一層相同的得不到焦點。
      第四層是個意外的層。嵌在這里的窗體會表顯出異樣的情況。唯一值得我們嵌入的理由是:它不會隨Explorer.exe進程的結束而關閉。


    用mfc實現就是這樣的代碼
    HWND hDesktop = ::FindWindow("Progman", NULL);
    hDesktop = ::GetWindow(hDesktop, GW_CHILD);
    CWnd* pWndDesktop = CWnd::FromHandle(hDesktop);
    this->SetParent(pWndDesktop);

    作者:未知 | 文章來源:未知 | 更新時間:2007-10-24 11:44:08

  • 上一篇文章:

  • 下一篇文章:

  • 相關文章:
    軟件開發中項目經理有那些職責
    “七分選型,三分軟件”的ERP法則
    C++函數對象count_if
    語法C# 問關鍵字之:base、this
    優化Ajax 為網站減負
    .Net下的分布式緩存
    復制SQL 數據庫時的問題
    認識Java中native方法
    p2p軟件如何穿透內網進行通信
    軟件程序編寫者的思路需要變化
    軟件技術
    · 開發語言
    · Java技術
    · .Net技術
    · 數據庫開發
    最新文章  
    ·搜集整理的asp.net的驗證方
    ·各種FOR循環結構的整理
    ·軟件項目開發中應該考慮那
    ·搜集整理的javascript sel
    ·軟件開發中項目經理有那些
    ·學習如何在Lambda表達式進
    ·C++基礎知識:結構體數據的
    ·C#實現短信發送程序的例子
    ·sun最近修補了一部分java的
    ·rss定制的另外一種實現方式
    ·delphi實現利用arp欺騙來實
    ·基礎學習:基于WF的流程框
    ·網絡編程中怎樣得知一次數
    ·如何逆序輸出單鏈表?
    ·軟件開發過程中的性能設計
    關于我們 | 軟件開發 | 下載試用 | 客服中心 | 聯系我們 | 友情鏈接 | 網站地圖 | 新疆電子地圖 | RSS訂閱
    版權所有 © 2016 新疆二域軟件開發網 www.vidoe666.cn All Rights Reserved 新ICP備14003571號
    新疆軟件開發總機:0991-4842803、4811639.
    客服QQ:596589785 ;地址:新疆烏魯木齊北京中路華聯大廈A-5C 郵編:830000
     
    野花影视大全在线观看免费,野花影视大全在线观看免费高清,小小影视大全在线观看免费观看
    <object id="ged8u"></object>
  • <dd id="ged8u"><noscript id="ged8u"></noscript></dd><rp id="ged8u"></rp>
  • <tbody id="ged8u"><noscript id="ged8u"></noscript></tbody>