 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
nelid Guest
|
Posted: Sat Apr 21, 2007 2:38 am Post subject: Outlook COM AddIn - PropertyPage and XP Theme Manifest |
|
|
Hi,
I write my first Outlook COM AddIn in Delphi 2006, with PropertyPage, but I haven't XP theme on my page.
How can I have ?
And my second question, why my page haven't width as other page?
Somebody please help me! (maybe Dimitri:))
sorry for my bad english:( |
|
| Back to top |
|
 |
Dmitry Streblechenko Guest
|
Posted: Sun Apr 22, 2007 2:41 am Post subject: Re: Outlook COM AddIn - PropertyPage and XP Theme Manifest |
|
|
Below is a copy of my reply to an "Outlook plugins and WinXP themes..."
thread from the Outlook-Dev Yahoo list posed back in 2003
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Manifest file is XML file describing how the app must be themed, you can
steal any existing file, the important part is it needs to be there and it
must be named as exeordllfilename.ext.manifest
Again, if you put the outlook.exe.manifest file into the same directory as
outlook.exe, you will theme Outlook as well as all the addins (which might
not be what you need), no extra work required.
To theme only your addin running under Outlook 2003 in Windows XP you will
need to to
1. Add the manifest file as a resource in your dll (below is what OutlookSpy
resource file includes)
2 24 OutSpy.dll.manifest
2. Before your controls' window handles are created, you need to activate
the
theming context. In Delphi most controls are derived from TWinControl,
overriding TWinControl.CreateHandle() method takes care of theming. I tried
to activate theming context once, but this was producing a bunch of weird
side effects because Delphi delays creation of child controls until it is
really required (e.g. when you switch to a page tab with child controls,
child controls are created as that moment, not when the whole page control
is
created). If your code does not do that, you can get away with using the
code
below for the whole window rather than each control.
Buffer : array[0..MAX_PATH] of Char;
act : ACTCTX;
bContextActivated : boolean ;
m_hActCtx : THANDLE ;
Cookie : ULONG ;
....
m_hActCtx:=0;
bContextActivated:=false;
//Windows XP and up
if (Win32Platform = VER_PLATFORM_WIN32_NT) and
((Win32MajorVersion > 5) or ((Win32MajorVersion = 5) and
(Win32MinorVersion >= 1)))
then begin
if GetModuleFileName(0, Buffer, SizeOf(Buffer)) > 0 then begin
//hosting exe (outlook.exe)
ZeroMemory(@act, SizeOf(act));
act.dwFlags := ACTCTX_FLAG_RESOURCE_NAME_VALID;
act.lpResourceName := MAKEINTRESOURCE(2); //there must be a manifest
resource in the dll
act.cbSize := sizeof(act);
act.lpSource := Buffer;
m_hActCtx := CreateActCtxA(act);
if (m_hActCtx <> 0) then begin
bContextActivated:=ActivateActCtx(m_hActCtx, Cookie);
end;
end;
end;
try
//old code that calls CreateParams(), CreateWindowEx(), etc goes here
finally
if bContextActivated then DeactivateActCtx(0, Cookie);
if m_hActCtx <> 0 then ReleaseActCtx(m_hActCtx);
end;
3. If you have any custom controls that do not rely on the standard window
classes (such as buttons, edits, etc), they must be modified to paint
themselves using theme functions.
4. Property pages - since property pages are regular ActiveX controls hosted
by Outlook, you need to paint the background of the control used as the
property page using page control tab body theme (TABP_BODY). Below is what
options page in OutlookSpy does, fTheme is HTHEME, defined as a class
member:
procedure TOptionsTabForm.WMPaint(var Message: TWMPaint);
var bHandled : boolean;
DC: HDC;
PS: TPaintStruct;
ThemeActivator : TThemeActivator;
begin
bHandled:=false;
if not FInitialized then begin
FInitialized:=true;
Align; //resize the container to occupy the whole client area of the
parent
//initialize themes
if (@OpenThemeData <> nil) then begin
ThemeActivator:=TThemeActivator.Create(2);
//if the theme cannot be activated, that means we are running under
//a theme-unaware version of Outlook
if ThemeActivator.Activated then fTheme:=OpenThemeData(Handle, 'TAB');
ThemeActivator.Free;
end;
end;
if fTheme <> 0 then begin
//Outlook is theme-aware
//draw the page control background
DC := Message.DC;
if DC = 0 then DC := BeginPaint(Handle, PS);
if S_OK = DrawThemeBackground(fTheme, DC, TABP_BODY, 0, ClientRect, nil)
then begin
bHandled:=true;
PaintControls(DC, nil);
end;
if Message.DC = 0 then EndPaint(Handle, PS);
end;
if bHandled
then Message.Result:=0
else inherited;
end;
TThemeActivator class is defined as follows:
//temporary activates themes when created, deactivates when destroyed
TThemeActivator = class(TObject)
private
act : ACTCTX;
bContextActivated : boolean ;
m_hActCtx : THANDLE ;
Cookie : ULONG ;
public
constructor Create(ResID : integer);
destructor Destroy;override;
property Activated : boolean read bContextActivated;
end;
constructor TThemeActivator.Create(ResID: integer);
var Buffer : array[0..MAX_PATH] of Char;
begin
m_hActCtx:=0;
bContextActivated:=false;
//Windows XP and up
if (Win32Platform = VER_PLATFORM_WIN32_NT) and
((Win32MajorVersion > 5) or ((Win32MajorVersion = 5) and
(Win32MinorVersion >= 1)))
then begin
if GetModuleFileName(0, Buffer, SizeOf(Buffer)) > 0 then begin //hosting
exe (outlook.exe)
ZeroMemory(@act, SizeOf(act));
act.dwFlags := ACTCTX_FLAG_RESOURCE_NAME_VALID;
act.lpResourceName := MAKEINTRESOURCE(ResID); //there must be a
manifest resource in the dll
act.cbSize := sizeof(act);
act.lpSource := Buffer;
m_hActCtx := CreateActCtxA(act);
if (m_hActCtx <> 0) then begin
bContextActivated:=ActivateActCtx(m_hActCtx, Cookie);
end;
end;
end;
end;
destructor TThemeActivator.Destroy;
begin
if bContextActivated then DeactivateActCtx(0, Cookie);
if m_hActCtx <> 0 then ReleaseActCtx(m_hActCtx);
inherited;
end;
"nelid" <lenkiew.debug (AT) debug (DOT) pl> wrote in message
news:f0bbst$p9o$1 (AT) atlantis (DOT) news.tpi.pl...
| Quote: | Hi,
I write my first Outlook COM AddIn in Delphi 2006, with PropertyPage, but
I haven't XP theme on my page.
How can I have ?
And my second question, why my page haven't width as other page?
Somebody please help me! (maybe Dimitri:))
sorry for my bad english:( |
|
|
| Back to top |
|
 |
Dmitry Streblechenko Guest
|
Posted: Sun Apr 22, 2007 2:44 am Post subject: Re: Outlook COM AddIn - PropertyPage and XP Theme Manifest |
|
|
Correction. I fixed TThemeActivator.Create implemantation since the code was
posted in 2003
constructor TThemeActivator.Create(ResID: integer);
var Buffer : array[0..MAX_PATH] of Char;
err : integer ;
begin
m_hActCtx:=0;
bContextActivated:=false;
//Windows XP and up
if (Win32Platform = VER_PLATFORM_WIN32_NT) and
((Win32MajorVersion > 5) or ((Win32MajorVersion = 5) and
(Win32MinorVersion >= 1)))
then begin
if GetModuleFileName(0, Buffer, SizeOf(Buffer)) > 0 then begin //hosting
exe (outlook.exe)
ZeroMemory(@act, SizeOf(act));
act.dwFlags := ACTCTX_FLAG_RESOURCE_NAME_VALID or
ACTCTX_FLAG_HMODULE_VALID;
act.lpResourceName := MAKEINTRESOURCE(ResID); //there must be a
manifest resource in the dll
act.cbSize := sizeof(act);
act.lpSource := Buffer;
act.hModule:=HInstance;
m_hActCtx := CreateActCtxA(act);
if (m_hActCtx <> 0) then begin
bContextActivated:=ActivateActCtx(m_hActCtx, Cookie);
if not bContextActivated then begin
err:=GetLastError;
if err = 0 then;
end;
end;
end;
end;
end;
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
"Dmitry Streblechenko" <dmitry (AT) dimastr (DOT) com> wrote in message
news:462a8461$1 (AT) newsgroups (DOT) borland.com...
| Quote: | Below is a copy of my reply to an "Outlook plugins and WinXP themes..."
thread from the Outlook-Dev Yahoo list posed back in 2003
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Manifest file is XML file describing how the app must be themed, you can
steal any existing file, the important part is it needs to be there and it
must be named as exeordllfilename.ext.manifest
Again, if you put the outlook.exe.manifest file into the same directory as
outlook.exe, you will theme Outlook as well as all the addins (which might
not be what you need), no extra work required.
To theme only your addin running under Outlook 2003 in Windows XP you will
need to to
1. Add the manifest file as a resource in your dll (below is what
OutlookSpy
resource file includes)
2 24 OutSpy.dll.manifest
2. Before your controls' window handles are created, you need to activate
the
theming context. In Delphi most controls are derived from TWinControl,
overriding TWinControl.CreateHandle() method takes care of theming. I
tried
to activate theming context once, but this was producing a bunch of weird
side effects because Delphi delays creation of child controls until it is
really required (e.g. when you switch to a page tab with child controls,
child controls are created as that moment, not when the whole page control
is
created). If your code does not do that, you can get away with using the
code
below for the whole window rather than each control.
Buffer : array[0..MAX_PATH] of Char;
act : ACTCTX;
bContextActivated : boolean ;
m_hActCtx : THANDLE ;
Cookie : ULONG ;
...
m_hActCtx:=0;
bContextActivated:=false;
//Windows XP and up
if (Win32Platform = VER_PLATFORM_WIN32_NT) and
((Win32MajorVersion > 5) or ((Win32MajorVersion = 5) and
(Win32MinorVersion >= 1)))
then begin
if GetModuleFileName(0, Buffer, SizeOf(Buffer)) > 0 then begin
//hosting exe (outlook.exe)
ZeroMemory(@act, SizeOf(act));
act.dwFlags := ACTCTX_FLAG_RESOURCE_NAME_VALID;
act.lpResourceName := MAKEINTRESOURCE(2); //there must be a manifest
resource in the dll
act.cbSize := sizeof(act);
act.lpSource := Buffer;
m_hActCtx := CreateActCtxA(act);
if (m_hActCtx <> 0) then begin
bContextActivated:=ActivateActCtx(m_hActCtx, Cookie);
end;
end;
end;
try
//old code that calls CreateParams(), CreateWindowEx(), etc goes here
finally
if bContextActivated then DeactivateActCtx(0, Cookie);
if m_hActCtx <> 0 then ReleaseActCtx(m_hActCtx);
end;
3. If you have any custom controls that do not rely on the standard window
classes (such as buttons, edits, etc), they must be modified to paint
themselves using theme functions.
4. Property pages - since property pages are regular ActiveX controls
hosted
by Outlook, you need to paint the background of the control used as the
property page using page control tab body theme (TABP_BODY). Below is what
options page in OutlookSpy does, fTheme is HTHEME, defined as a class
member:
procedure TOptionsTabForm.WMPaint(var Message: TWMPaint);
var bHandled : boolean;
DC: HDC;
PS: TPaintStruct;
ThemeActivator : TThemeActivator;
begin
bHandled:=false;
if not FInitialized then begin
FInitialized:=true;
Align; //resize the container to occupy the whole client area of the
parent
//initialize themes
if (@OpenThemeData <> nil) then begin
ThemeActivator:=TThemeActivator.Create(2);
//if the theme cannot be activated, that means we are running under
//a theme-unaware version of Outlook
if ThemeActivator.Activated then fTheme:=OpenThemeData(Handle, 'TAB');
ThemeActivator.Free;
end;
end;
if fTheme <> 0 then begin
//Outlook is theme-aware
//draw the page control background
DC := Message.DC;
if DC = 0 then DC := BeginPaint(Handle, PS);
if S_OK = DrawThemeBackground(fTheme, DC, TABP_BODY, 0, ClientRect, nil)
then begin
bHandled:=true;
PaintControls(DC, nil);
end;
if Message.DC = 0 then EndPaint(Handle, PS);
end;
if bHandled
then Message.Result:=0
else inherited;
end;
TThemeActivator class is defined as follows:
//temporary activates themes when created, deactivates when destroyed
TThemeActivator = class(TObject)
private
act : ACTCTX;
bContextActivated : boolean ;
m_hActCtx : THANDLE ;
Cookie : ULONG ;
public
constructor Create(ResID : integer);
destructor Destroy;override;
property Activated : boolean read bContextActivated;
end;
constructor TThemeActivator.Create(ResID: integer);
var Buffer : array[0..MAX_PATH] of Char;
begin
m_hActCtx:=0;
bContextActivated:=false;
//Windows XP and up
if (Win32Platform = VER_PLATFORM_WIN32_NT) and
((Win32MajorVersion > 5) or ((Win32MajorVersion = 5) and
(Win32MinorVersion >= 1)))
then begin
if GetModuleFileName(0, Buffer, SizeOf(Buffer)) > 0 then begin //hosting
exe (outlook.exe)
ZeroMemory(@act, SizeOf(act));
act.dwFlags := ACTCTX_FLAG_RESOURCE_NAME_VALID;
act.lpResourceName := MAKEINTRESOURCE(ResID); //there must be a
manifest resource in the dll
act.cbSize := sizeof(act);
act.lpSource := Buffer;
m_hActCtx := CreateActCtxA(act);
if (m_hActCtx <> 0) then begin
bContextActivated:=ActivateActCtx(m_hActCtx, Cookie);
end;
end;
end;
end;
destructor TThemeActivator.Destroy;
begin
if bContextActivated then DeactivateActCtx(0, Cookie);
if m_hActCtx <> 0 then ReleaseActCtx(m_hActCtx);
inherited;
end;
"nelid" <lenkiew.debug (AT) debug (DOT) pl> wrote in message
news:f0bbst$p9o$1 (AT) atlantis (DOT) news.tpi.pl...
Hi,
I write my first Outlook COM AddIn in Delphi 2006, with PropertyPage, but
I haven't XP theme on my page.
How can I have ?
And my second question, why my page haven't width as other page?
Somebody please help me! (maybe Dimitri:))
sorry for my bad english:(
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|