如何使Win32 應用程式相容系統控制項的主題

2021-07-14 14:53:45 字數 2950 閱讀 3437

最近在學習win32程式設計過程中開發了許多demo,但是發現這些demo使用的控制項風格還是很老舊的win9x時代的控制項。網上搜了一下在應用程式中加入一下**,可以使程式相容當前系統的控制項風格。

#pragma comment(linker,"/manifestdependency:\"type='win32' name='microsoft.windows.common-controls' version='6.0.0.0' processorarchitecture='x86' publickeytoken='6595b64144ccf1df' language='*'\"")

具體原理**

什麼是.manifest檔案

[現象]

對這個問題的研究是起源於這麼乙個現象:當你用vc++2005(或者其它.net)寫程式後,在自己的計算機上能毫無問題地執行,但是當把此exe檔案拷貝到別人電腦上時,便不能執行了,大致的錯誤提示如下:應用程式配置不正確,請重新安裝程式……或者是msvcr80d.dll 沒有找到什麼的(我記得不是很清楚,不過大致是這樣的)

[分析]

看到這樣的提示,當然不會傻到重灌咯。第一反應應該是什麼配置有問題、或者是缺少了什麼依賴的庫檔案;於是我就根據以前windows缺少庫檔案的經驗,把所有庫檔案(××.dll)統統一股腦地複製到當前資料夾下來,滿心歡喜以為可以執行了,以執行……@#¥@#%¥……還是掛了。

[探索]

於是開始網上搜尋,我google,我擺渡;漸漸我發現,這一切都和乙個叫做***.manifest 型別的檔案發生關係,那麼到底什麼是 .manifest 檔案呢?他有什麼用,以前為什麼沒有?

後來,經過艱苦努力,終於得知,原來這一切都是windows 的assembly manifest搞的鬼。這個東東的作用就是為了解決 以前windows上的「dll 地獄」 問題才產生的新的dll管理解決方案。大家知道,dll是動態載入共享庫,同乙個dll可能被多個程式所使用,而所謂「dll 地獄」就是當不通程式依賴的dll相同,但版本不同時,由於系統不能分辨到底哪個是哪個,所以載入錯了dll版本,然後就掛了。於是蓋茨就吸取了教訓,搞了乙個程式集清單的東東,每個程式都要有乙個清單,這個清單存再和自己應用程式同名的.manifest檔案中,裡面列出其所需要的所有依賴,這兒所列出的依賴可不是簡單地靠檔案明來區分的,而是根據一種叫做「強檔名」的東西區分的,那麼什麼是強檔案明呢?我們來看一下這個.manifest檔案便知道了。

<?xml version='1.0' encoding='utf-8' standalone='yes'?>

我們發現原來這是乙個xml格式的檔案,其中這一部分指明了其依賴於乙個名字叫做microsoft.vc80.crt的庫。但是我們發現,屬性裡面還有其它的東東,分別是

type系統型別,version版本號,processorarchitecture平台環境,publickeytoken公匙(一般用來標示乙個公司)……把他們加在一起便成了「強檔名」了,有了這種「強檔名」,我們就可以根據其區分不同的版本、不同的平台……總之,有了這種強檔名,系統中可以有多個不同版本的相同的庫共存而不會發生衝突。

[深入]

恩,那麼現在,我們就來具體了解一下這一套機制。

首先是強弱檔名的問題。正如上面提到的那樣,為了區分不同版本或不同廠商生成的相同的程式集,必須用乙個assembly manifest程式清單來列出我這個程式集的強檔名--慢著,到這裡你可能會問:剛才不是說assembly manifest程式清單是列出其所依賴的程式集的強檔名呢,怎麼這裡變成了當前檔案的強檔案明了呢?其實,assembly manifest程式清單有兩部分功能,上面這個例項之所以標註了其所依賴的檔案的強檔名是因為其是客戶端的assembly manifest,在服務端有另外乙個manifest 來標註。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

phruexlaez8bwmld8vlo5udanre=

7ay1jqouvk3u/6bywboagggafbc=

hwq8zaztsmekvxwfba6bnv4heow=

這個便是從windows\winsxs\manifests目錄下取出來的乙個manifest檔案,再這個資料夾下有一陀子這種xml格式的manifest檔案,其是服務端的程式清單。winsxs是windows xp以上版本提供的[blue]非託管並行快取(side-by-side catche)[/blue]裡面安裝了各種版本的經過強檔名簽名的系統庫,而上面這個檔案正是標註了系統中microsoft.vc80.crt的乙個版本的強檔名簽名,如果其和客戶端。.manifest 清單裡面所列出的依賴項對上的話,就會被載入。剛才說的side-by-side 是指各種不同的版本並行執行。

上面這個服務端manifest檔案中標籤具體指明了當前強檔名簽名的到底是哪乙個檔案,其中還有這個檔案的hash簽名,以確保檔案的完整性。

好了,有了這一套機制,就可以非常非常安全地進行庫檔案關聯了,但是、但是貌似還有乙個一直困擾我們的問題:這套機制安全是安全了,但是卻失去了以前良好的前後版本相容性,即如果你的系統庫發生了公升級,那麼服務端的版本號發生了變化,那豈不是所有服務端程式都不能使用了嗎?其實,windows還使用乙個policy的策略檔案來確認對映關係。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

這便是在windows\winsxs\policies目錄下的乙個policy檔案,其中標籤便指定了所有8.0.41204.256-8.0.50608.0變本的客戶需求對映到8.0.50727.42這個我現在系統中安裝的比較新的版本的庫。當然我們也能對別的字段進行對映,這樣便能很好解決系統公升級帶來的問題。

Win32應用程式

建立乙個win32應用程式的步驟。1.編寫winmain函式,可以在msdn上查詢並複製。2.設計視窗類 wndclass 3.註冊視窗類。4.建立視窗.5.顯示並更新視窗。6.編寫訊息迴圈.7.編寫視窗過程函式。視窗過程函式的語法,可通過msdn檢視wndclass的ipfnwndproc成員變數...

Win32應用程式入口函式

include int winapi winmain hinstance hinstance,hinstance hprevinstance,lpstr lpcmdline,int ncmdshow 1.windows.h是開發window應用程式必須要包含 2.hinstance是當前程式例項控制...

Win32應用程式是什麼

win32應用程式是指可以在32位或以上windows系統中執行的程式。區別於dos應用程式,win16應用程式。dos應用程式是以前的dos作業系統下的應dao用程式。win16是以前windows3.0 3.1 3.2作業系統下的應用程式。win32是winnt 2000 xp 2003作業系統...