• Thứ Tư, 27/09/2006 14:26 (GMT+7)

    Hỗ trợ XP Themes trên Visual C++ 2005: Tưởng khó mà dễ!

    Bài viết này muốn đề cập đến các dự án dạng Win32 Application (dùng thuần Win32 API). Không như các ứng dụng MFC tự động hỗ trợ XP Theme ngay khi tạo dự án, các ứng dụng Win32 này vẫn mang dáng dấp các thành phần giao diện từ thời "xa xưa". Chắc chắn là các bạn muốn "thổi hồn thời đại" vào ứng dụng của mình, bắt nó hỗ trợ giao diện XP. Tôi cũng vậy và tôi đã có một buổi toát mồ hôi đánh vật với Visual C++ 2005!

    Đối với các phiên bản trước, cách đơn giản nhất là copy file MyApp.exe.manifest vào thư mục chứa file MyApp.exe. File này chắc các bạn đã biết, nó thông báo cho Windows XP sử dụng file Comctl32.dll phiên bản 6.0 để ứng dụng có thể dùng XP theme, nếu không Windows chỉ gọi phiên bản 5.82, khi đó ứng dụng chỉ có giao diện kiểu cũ.

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

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="CompanyName.ProductName.YourApplication" type="win32">

    </assemblyIdentity>

    <description>Your application description here.</description>

    <dependency>

    <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*">

    </assemblyIdentity>

    </dependentAssembly>

    </dependency>

    </assembly>

    Tôi cũng làm tương tự nhưng những gì tôi nhận được là một thông báo lỗi khó hiểu.

    Tôi đành sử dụng cách "chính qui" hơn là đưa thẳng file .manifest vào trong tài nguyên của dự án – cách đã được dùng hiệu quả trên Visual C++ 7.1 trở về trước. Cách này chắc nhiều bạn biết, nhưng tôi vẫn muốn nêu lại:

    - Trong thẻ Resource view, dùng Add Resource thêm file *.manifest vào

    - Mở file *.rc bằng cách chọn View code, sửa đổi dạng tài nguyên cho file *.manifest là RT_MANIFEST và tên tài nguyên là IDR_MANIFEST

    - Mở file Resource.h, thêm 1 dòng #define IDR_MANIFEST 1

    - Dịch lại ứng dụng

    Cách này cho kết quả rất tốt trên các phiên bản trước, nhưng lần này tôi lại nhận được thông báo lỗi khi dịch: tài nguyên MANIFEST đã bị lặp lại 2 lần.

    Đến khi dùng Resource Hacker (hay là dùng chính VS IDE) để mở file *.exe (nguyên gốc, chưa có chỉnh sửa gì) do VC++ tạo ra, tôi mới hiểu được nguyên nhân: trong file *.exe này đã có sẵn tài nguyên manifest, đó là lí do trình dịch báo lỗi trùng.


    Nội dung tài nguyên này như sau:

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

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

    <dependency>

    <dependentAssembly>

    <assemblyIdentity

    type="win32" name="Microsoft.VC80.DebugCRT"

    version="8.0.50608.0" processorArchitecture="x86"

    publicKeyToken="1fc8b3b9a1e18e3b">

    </assemblyIdentity>

    </dependentAssembly>

    </dependency>

    </assembly>

    Đến đây, ta hiểu được nguyên nhân của thông báo lỗi khó hiểu ở trên. Nó chỉ cho ứng dụng liên kết đến thư viện CRT của VC++ (file MSVCR80D.DLL - vì đây là phiên bản debug), nhưng khi đó file MyApp.exe.manifest đã "nhảy ra" chiếm quyền, nên ứng dụng không thể liên kết được đến thư viện này. Bản thân nội dung tài nguyên này lại không chứa phần chỉ dẫn để sử dụng file Comctl32.dll ver 6.0 – điều kiện để ứng dụng hỗ trợ XP theme. Một cách đơn giản là bạn bổ sung một đoạn XML có nội dung sau vào phần tài nguyên ở trên (vào trước tag </assambly>), rồi ghi lại.

    <dependency>

    <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*">

    </assemblyIdentity>

    </dependentAssembly>

    </dependency>

    Nhưng như thế thì thủ công quá! Tôi tình cờ phát hiện ra một cách đơn giản đến không ngờ: Bạn chỉ cần thêm file *.manifest (tên file không quan trọng, có nội dung như file MyApp.exe.manifest ở trên) ở thẻ Solution Explorer (không phải là Resource View), nhấn chuột phải vào dự án, chọn Add/ Existing Item. Cho dịch lại, thế là xong. Khi dịch, bạn sẽ thấy có thông báo:

    Compiling resources...

    Compiling manifest to resources...

    Sau khi biên dịch xong, ứng dụng của bạn sẽ hỗ trợ XP theme.

    Nếu bây giờ bạn dùng Resource Hacker để mở lại file *.exe thì bạn sẽ thấy tài nguyên 24/1/1033 phía trên đã bao hàm cả phần chỉ định liên kết với thư viện CRT và Comctl32.dll 6.0.

    Nếu thích, bạn có thể sửa lại file MyApp.exe.manifest để nó chứa cả phần chỉ định đến thư viện MSVCR80.DLL và đặt cùng với MyApp.exe chứ không nhất thiết phải đưa nó vào ứng dụng.

    Hi vọng bài viết nhỏ này sẽ giúp ích cho các bạn. Rất mong được các bạn trao đổi ý kiến.

    Mai Văn Quân
    Email: Vimvq1987@gmail.com

    ID: A0609_125