自己编写的dll中窗体无法使用xp样式。用的是delphi 7.0,使用XPMenifest来实现那个资源xml(300分)

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,死活不行。编写的控制面板程序就是不能实现xp样式。
抄写并修改themes.pas.作如下修改
//FNewComCtrls := GetComCtlVersion >= ComCtlVersionIE6;
FNewComCtrls := True;
结果,除了TGroupBox的样式XP化了,其他都不行。
此时GetComCtlVersion = 337762 即comctl32.dll=5.8.xxx.2180那个版本。
察看reshacker对这个cpl的分析,24/1/0是存在合法xml的menifest说明的。

那位高人见教则个,愿送1000分
 

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
察看microsoft文档1小时,搞定了此问题。24/123/*才能使rundll32启动的程序有效,而不是24/1/*;但是依据分析google工具条和微软的说明,24/2/*是其他dll程序应当采取的方式。可是我的IE工具栏dll依然无法实现xp样式化。

继续此问题,转移到IE工具条的xp样式化。继续1000分。
 
Z

zhaokaien

Unregistered / Unconfirmed
GUEST, unregistred user!
这个问题有难度
 

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
分析最后确认24/2/*是正确的,问题初步推断与windows.pas过旧有关,具体可能为ISOLATION_AWARE_ENABLED不支持。目前使用delphi 7的1.1patch后依然不行。
谁放上一个2006的windows.pas让偶试试?
我cdma的卡一周也down下2006来 /(-o-)/
 

网中戏

Unregistered / Unconfirmed
GUEST, unregistred user!
L

leehq

Unregistered / Unconfirmed
GUEST, unregistred user!
在程序和DLL里都加上uses XPMan!
 

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
to: leehq;

请试过了再说。XPMan是根本不行的。
 
L

leehq

Unregistered / Unconfirmed
GUEST, unregistred user!
有些控件不能XP化,比如DBGrid,
是不是这个原因?
 

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
不是,原因见http://delphi.newswhat.com/geoxml/forumhistorythread?groupname=delphi-gems.support.general&messageid=bi165v$sn8$1@talkto.net
 

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
没人回答也罢了,谁给我一个delphi2006的windows.pas, 我分送了算了
 

在世寻欢

Unregistered / Unconfirmed
GUEST, unregistred user!
XP风格最难看了,不要以为谁都喜欢。
还是朴素的好,软件的质量才是首要。
 

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
讨论了这么多,老兄还没看出来,这个问题不在于是否XP风格,而在于commctrl 6是否能在dll成功挂载吗?目标既然是插件类型的dll,不符合用户的自定义Theme,插在IE里时候有多丑?更何况无法知道用户的Theme到底是TigerX还是Vista...,所以这个问题不解决是不行的。
 

章慧

Unregistered / Unconfirmed
GUEST, unregistred user!
又是一个自己搞定的问题,巨郁闷!不知道挂了近万分了。
弄了2周参读VC,C#的代码,终于搞定了本问题。挂在这儿方便后人吧,免得后辈都跟着外国人说Delphi写dll灭法XP化。

以下代码,保存直接use, 即可使IE插件DLL XP样式化。无需res文件了。也不要引用Themes或者commcontrol。至于Office系列,控制面板,普通程序,那就没那么多时间测,谁有兴趣自己搞吧。只要坚信delphi什么都能搞定就OK了。
代码:
Unit DLLXPTheming;

Interface

// *********************************
// Author: Hibiki, kirikawa
// Date:   Sep 5th, 2006, 17:40 
// *********************************

 Uses
  Windows, Classes, SysUtils;

 Const
  ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID = ($00000001);
  ACTCTX_FLAG_LANGID_VALID = ($00000002);
  ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID = ($00000004);
  ACTCTX_FLAG_RESOURCE_NAME_VALID = ($00000008);
  ACTCTX_FLAG_SET_PROCESS_DEFAULT = ($00000010);
  ACTCTX_FLAG_APPLICATION_NAME_VALID = ($00000020);
  ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF = ($00000040);
  ACTCTX_FLAG_HMODULE_VALID = ($00000080);
  ISOLATIONAWARE_MANIFEST_RESOURCE_ID = 2;

 Type
  USHORT = Word;
  ULONG_PTR = LongWord;
  PULONG_PTR = ^ULONG_PTR;
  HANDLE = THandle;
  PVOID = Pointer;
  tagACTCTXA = Record
                cbSize: ULONG;
                dwFlags: DWORD;
                lpSource: LPCSTR;
                wProcessorArchitecture: USHORT;
                wLangId: LANGID;
                lpAssemblyDirectory: LPCSTR;
                lpResourceName: LPCSTR;
                lpApplicationName: LPCSTR;
                hModule: hModule;
               End;

  ACTCTXA = tagACTCTXA;
  PACTCTXA = ^ACTCTXA;
  TActCtxA = ACTCTXA;

  ACTCTX = ACTCTXA;
  PACTCTX = PACTCTXA;
  TActCtx = TActCtxA;

 Var
  CreateActCtx: function(pActCtx: pointer): THandle; stdcall;
  ActivateActCtx: function(hActCtx: THandle; lpCookie: pointer): Boolean; stdcall;

Implementation

 Var
  ctxHandle: THandle;
  krnl: HMODULE;
  HandleActCtx: THandle = 0;

Function GetDLLName: String;
 Var
  charPath: Array [0..2047] Of Char;
  sFile: String;
 Begin
  ZeroMemory(Addr(charPath[0]), 2048);
  GetModuleFileName(HInstance, charPath, 2048);
  sFile := charPath;
  Result := sFile;
 End;

Function BuildManifest: TStringList;
 Begin
  Result := TStringList.Create;
  Result.Add('<?xml version="1.0" encoding="utf-8" standalone="yes"?>');
  Result.Add('<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">');
  Result.Add('    <assemblyIdentity');
  Result.Add('    version="1.0.0.0"');
  Result.Add('    processorArchitecture="X86"');
  Result.Add('    name="Kirikawa.Kanibar.IEToolBand"');
  Result.Add('    type="win32"');
  Result.Add('/>');
  Result.Add('    <description>Animation Search Kit for Internet Explorer.</description>');
  Result.Add('    <dependency>');
  Result.Add('        <dependentAssembly>');
  Result.Add('            <assemblyIdentity');
  Result.Add('            type="win32"');
  Result.Add('            name="Microsoft.Windows.Common-Controls"');
  Result.Add('            version="6.0.0.0"');
  Result.Add('            processorArchitecture="X86"');
  Result.Add('            publicKeyToken="6595b64144ccf1df"');
  Result.Add('            language="*"');
  Result.Add('        />');
  Result.Add('        </dependentAssembly>');
  Result.Add('    </dependency>');
  Result.Add('</assembly>');
 End; 

Procedure ActivateTheming;
 Var
  ctx: ACTCTX;
  path, manifest, s: String;
  d: TStringList;
 Begin
  if HandleActCtx <> 0 then Exit;
  krnl := GetModuleHandle('KERNEL32.DLL');
  CreateActCtx := GetProcAddress(krnl, 'CreateActCtxA');
  ActivateActCtx := GetProcAddress(krnl, 'ActivateActCtx');
  if (not Assigned(CreateActCtx)) or (not Assigned(ActivateActCtx)) then Exit;
  FillChar(ctx, SizeOf(ctx), 0);
  ctx.cbSize := SizeOf(ctx);
  ctx.dwFlags := ACTCTX_FLAG_SET_PROCESS_DEFAULT or ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
  s := GetDLLName;
  path := ExtractFilePath(s);
  manifest := ExtractFileName(s) + '.manifest';
  s := path + '/' + manifest;
  d := BuildManifest;
  Try
   If Not FileExists(s) Then d.SaveToFile(s);
  Except
  End;
  d.Free;
  ctx.lpSource := pChar(s);
  ctx.lpAssemblyDirectory := pChar(path);
  ctxhandle := CreateActCtx(addr(ctx));
 End;

Initialization
 Try
  ActivateTheming;
 Except
 End; 

End.
 

Similar threads

顶部