Hi, to see how easy (or not) it would be to make the controls use themes, I tried to get themed buttons; the result is the attached patch (to try it out, you need an .msstyles file and appropriate registry setup). It's probably not perfect as it is, comments/questions are welcome.
Screenshot: http://img87.exs.cx/my.php?loc=img87&image=winewiththemedbuttons3xh.png
Some funny side effect when theming is enabled: applications show up in standard colors, but as soon as the first button is created, the colors switch to the theme's colors. I guess opening the theme data in the button code triggers some uxtheme initialization that in turn changes the system colors.
Also, all applications get themed buttons, which diverges from WinXPs behaviour and may or may not be desired for some apps.
-f.r.
Index: dlls/user/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/user/Makefile.in,v retrieving revision 1.88 diff -u -r1.88 Makefile.in --- dlls/user/Makefile.in 10 Mar 2005 15:47:53 -0000 1.88 +++ dlls/user/Makefile.in 21 Mar 2005 18:46:31 -0000 @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = user32.dll -IMPORTS = gdi32 advapi32 kernel32 ntdll +IMPORTS = gdi32 advapi32 kernel32 uxtheme ntdll EXTRALIBS = $(LIBUNICODE)
SPEC_SRCS16 = \ Index: dlls/user/button.c =================================================================== RCS file: /home/wine/wine/dlls/user/button.c,v retrieving revision 1.6 diff -u -r1.6 button.c --- dlls/user/button.c 23 Dec 2004 17:21:05 -0000 1.6 +++ dlls/user/button.c 21 Mar 2005 18:46:32 -0000 @@ -71,6 +71,9 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winuser.h" /* Indirectly required by uxtheme.h */ +#include "uxtheme.h" +#include "tmschema.h" #include "wine/winuser16.h" #include "controls.h" #include "user_private.h" @@ -79,7 +82,8 @@ #define STATE_GWL_OFFSET 0 #define HFONT_GWL_OFFSET (sizeof(LONG)) #define HIMAGE_GWL_OFFSET (HFONT_GWL_OFFSET+sizeof(HFONT)) -#define NB_EXTRA_BYTES (HIMAGE_GWL_OFFSET+sizeof(HANDLE)) +#define HTHEME_GWL_OFFSET (HIMAGE_GWL_OFFSET+sizeof(HANDLE)) +#define NB_EXTRA_BYTES (HTHEME_GWL_OFFSET+sizeof(HTHEME))
/* Button state values */ #define BUTTON_UNCHECKED 0x00 @@ -95,6 +99,7 @@
static UINT BUTTON_CalcLabelRect( HWND hwnd, HDC hdc, RECT *rc ); static void PB_Paint( HWND hwnd, HDC hDC, UINT action ); +static void PB_PaintThemed( HWND hwnd, HDC hDC, UINT action ); static void CB_Paint( HWND hwnd, HDC hDC, UINT action ); static void GB_Paint( HWND hwnd, HDC hDC, UINT action ); static void UB_Paint( HWND hwnd, HDC hDC, UINT action ); @@ -123,7 +128,7 @@
typedef void (*pfPaint)( HWND hwnd, HDC hdc, UINT action );
-static const pfPaint btnPaintFunc[MAX_BTN_TYPE] = +static const pfPaint btnUnthemedPaintFunc[MAX_BTN_TYPE] = { PB_Paint, /* BS_PUSHBUTTON */ PB_Paint, /* BS_DEFPUSHBUTTON */ @@ -139,6 +144,22 @@ OB_Paint /* BS_OWNERDRAW */ };
+static const pfPaint btnThemedPaintFunc[MAX_BTN_TYPE] = +{ + PB_PaintThemed, /* BS_PUSHBUTTON */ + PB_PaintThemed, /* BS_DEFPUSHBUTTON */ + CB_Paint, /* BS_CHECKBOX */ + CB_Paint, /* BS_AUTOCHECKBOX */ + CB_Paint, /* BS_RADIOBUTTON */ + CB_Paint, /* BS_3STATE */ + CB_Paint, /* BS_AUTO3STATE */ + GB_Paint, /* BS_GROUPBOX */ + UB_Paint, /* BS_USERBUTTON */ + CB_Paint, /* BS_AUTORADIOBUTTON */ + NULL, /* Not defined */ + OB_Paint /* BS_OWNERDRAW */ +}; + static HBITMAP hbitmapCheckBoxes = 0; static WORD checkBoxWidth = 0, checkBoxHeight = 0;
@@ -183,9 +204,26 @@ return (window_style & 0x0f); }
+inline static HTHEME get_button_theme( HWND hwnd ) +{ + return (HTHEME)GetWindowLongPtrW( hwnd, HTHEME_GWL_OFFSET ); +} + +inline static void set_button_theme( HWND hwnd, HTHEME theme ) +{ + SetWindowLongPtrW( hwnd, HTHEME_GWL_OFFSET, (ULONG_PTR)theme ); +} + +inline static const pfPaint* get_paint_funcs ( HWND hwnd ) +{ + HTHEME theme = get_button_theme( hwnd ); + return ( theme != NULL ) ? btnThemedPaintFunc : btnUnthemedPaintFunc; +} + /* paint a button of any type */ inline static void paint_button( HWND hwnd, LONG style, UINT action ) { + const pfPaint* btnPaintFunc = get_paint_funcs( hwnd ); if (btnPaintFunc[style] && IsWindowVisible(hwnd)) { HDC hdc = GetDC( hwnd ); @@ -215,6 +253,9 @@ UINT btn_type = get_button_type( style ); LONG state; HANDLE oldHbitmap; + static const WCHAR themeClass[] = { 'B','u','t','t','o','n',0 }; + HTHEME theme; + const pfPaint* btnPaintFunc = get_paint_funcs( hWnd );
pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); @@ -249,8 +290,24 @@ if (btn_type >= MAX_BTN_TYPE) return -1; /* abort */ set_button_state( hWnd, BUTTON_UNCHECKED ); + theme = OpenThemeData( hWnd, themeClass ); + set_button_theme( hWnd, theme ); return 0; + + case WM_DESTROY: + theme = get_button_theme( hWnd ); + if ( theme != NULL ) + CloseThemeData ( theme ); + break;
+ case WM_THEMECHANGED: + theme = get_button_theme( hWnd ); + if ( theme != NULL ) + CloseThemeData ( theme ); + theme = OpenThemeData( hWnd, themeClass ); + set_button_theme( hWnd, theme ); + break; + case WM_ERASEBKGND: if (btn_type == BS_OWNERDRAW) { @@ -842,6 +899,39 @@ SetBkMode(hDC, oldBkMode); }
+static void PB_PaintThemed( HWND hwnd, HDC hDC, UINT action ) +{ + LONG state = get_button_state( hwnd ); + LONG style = GetWindowLongW( hwnd, GWL_STYLE ); + BOOL pushedState = (state & BUTTON_HIGHLIGHTED); + HTHEME theme = get_button_theme( hwnd ); + int partID = BP_PUSHBUTTON; + int stateID; + RECT rc; + WCHAR *text = NULL; + BOOL disabledState = !IsWindowEnabled( hwnd ); + + GetClientRect( hwnd, &rc ); + if (disabledState) + stateID = PBS_DISABLED; + else if (pushedState) + stateID = PBS_PRESSED; + else if (( get_button_type(style) == BS_DEFPUSHBUTTON ) + || ( state & BUTTON_HASFOCUS )) + stateID = PBS_DEFAULTED; + else + stateID = PBS_NORMAL; + + DrawThemeBackground( theme, hDC, partID, stateID, &rc, NULL); + + if (( text = get_button_text( hwnd ) ) != NULL ) + { + if ((style & (BS_ICON|BS_BITMAP)) == BS_TEXT) + DrawThemeText( theme, hDC, partID, stateID, text, -1, + BUTTON_BStoDT(style), 0, &rc ); + } +} + /********************************************************************** * Check Box & Radio Button Functions */
On Mon, 21 Mar 2005 20:05:57 +0100, Frank Richter wrote:
Hi, to see how easy (or not) it would be to make the controls use themes, I tried to get themed buttons; the result is the attached patch (to try it out, you need an .msstyles file and appropriate registry setup). It's probably not perfect as it is, comments/questions are welcome.
Hey, brilliant work! Definitely submit this - it doesn't matter if not everything is themed all at once, this can be a long term project and the approach you've taken seems to be a good one.
Yes XP does not theme all apps for compatibility reasons. Once more of our controls are themable I guess we can start to worry about switching it on at the right time.
I'd suggest posting this to wine-patches and seeing what happens. Once we get it into CVS, would you be willing to move on and do the other controls?
thanks -mike
On 22.03.2005 00:18, Mike Hearn wrote:
Once we get it into CVS, would you be willing to move on and do the other controls?
Okay, I'll see what I can do.
-f.r.
"Frank Richter" resqu@gmx.ch wrote:
to see how easy (or not) it would be to make the controls use themes, I tried to get themed buttons; the result is the attached patch (to try it out, you need an .msstyles file and appropriate registry setup). It's probably not perfect as it is, comments/questions are welcome.
Screenshot: http://img87.exs.cx/my.php?loc=img87&image=winewiththemedbuttons3xh.png
Some funny side effect when theming is enabled: applications show up in standard colors, but as soon as the first button is created, the colors switch to the theme's colors. I guess opening the theme data in the button code triggers some uxtheme initialization that in turn changes the system colors.
Also, all applications get themed buttons, which diverges from WinXPs behaviour and may or may not be desired for some apps.
user32 can not depend on uxtheme or any other high level dll. You need to make all the work inside of uxtheme by subclassing/patching every class you wish to change the painting for, and do all the painting inside of uxtheme. I'm not sure how to do it cleanly without adding an explicit dependency of every app on uxtheme. Do you know how Windows does themeing on low level?
On 22.03.2005 09:22, Dmitry Timoshkov wrote:
user32 can not depend on uxtheme or any other high level dll. You need to make all the work inside of uxtheme by subclassing/patching every class you wish to change the painting for, and do all the painting inside of uxtheme. I'm not sure how to do it cleanly without adding an explicit dependency of every app on uxtheme. Do you know how Windows does themeing on low level?
Unfortunately, subclassing from uxtheme or so is probably a magnitude more complicated than the straightforward approach to do the theming in the controls themselves. Apparently, having user depending on uxtheme seems to work fine. Are there any specific concerns you have about a user->uxtheme dependency?
How Windows is doing theming I don't know completely. You enable theming by adding a manifest to the executable which instructs Windows to load comctl32.dll version 6.0 instead of version 5.x from system32/. That makes me believe that actually comctl32.dll is responsible for applying themes to controls (and not uxtheme); how it does it exactly, I don't know. Subclassing is a good guess I'd think, or maybe something like re-registering the standard control classes (if that is possible).
However, Windows also themes the non-client area of (almost) all apps even if they don't use comctl32 6.0. That must happen somewhere, too.
-f.r.
Frank Richter resqu@gmx.ch writes:
How Windows is doing theming I don't know completely. You enable theming by adding a manifest to the executable which instructs Windows to load comctl32.dll version 6.0 instead of version 5.x from system32/. That makes me believe that actually comctl32.dll is responsible for applying themes to controls (and not uxtheme); how it does it exactly, I don't know. Subclassing is a good guess I'd think, or maybe something like re-registering the standard control classes (if that is possible).
However, Windows also themes the non-client area of (almost) all apps even if they don't use comctl32 6.0. That must happen somewhere, too.
Then the first thing to do is to figure out exactly how Windows does it, and do it the same way.
Alexandre Julliard wrote:
Frank Richter resqu@gmx.ch writes:
How Windows is doing theming I don't know completely. You enable theming by adding a manifest to the executable which instructs Windows to load comctl32.dll version 6.0 instead of version 5.x from system32/. That makes me believe that actually comctl32.dll is responsible for applying themes to controls (and not uxtheme); how it does it exactly, I don't know. Subclassing is a good guess I'd think, or maybe something like re-registering the standard control classes (if that is possible).
However, Windows also themes the non-client area of (almost) all apps even if they don't use comctl32 6.0. That must happen somewhere, too.
Then the first thing to do is to figure out exactly how Windows does it, and do it the same way.
typedef DWORD (CALLBACK * USERAPIHOOKPROC)(HINSTANCE hInstance, FARPROC *fnUserApis);
DWORD WINAPI RegisterUserApiHook(HINSTANCE hInstance, USERAPIHOOKPROC fnUserApiHook);
fnUserApis is an array of User functions that can be overridden.
RegisterUserApiHook is a function that is called once for the entire system and then user32 loads the specified module for each process and calls the specified fnUserApiHook function for that process. It is a cumbersome interface that may not be worth duplicating.
Rob
On 22.03.2005 17:00, Alexandre Julliard wrote:
Then the first thing to do is to figure out exactly how Windows does it, and do it the same way.
Most interesting is probably to find out how the standard controls from user32 are themed. Poking a bit around in comctl32 6.0, it seems that it actually just registers the standard classes with RegisterClassW, nothing more. AFAIK you can't register a class when the class name is already used, so it would be interesting to know why comctl32.dll can get away with it.
-f.r.
Frank Richter wrote:
Most interesting is probably to find out how the standard controls from user32 are themed. Poking a bit around in comctl32 6.0, it seems that it actually just registers the standard classes with RegisterClassW, nothing more. AFAIK you can't register a class when the class name is already used, so it would be interesting to know why comctl32.dll can get away with it.
Maybe it only register as per Process, which makes sense. And it does that before any window is displayed. Actually I know when. (A bug I had) it does it in the InitCommonControlsEx call. Not even in the DLLMain. An app that needs theming needs 3 things. 1. Link to comctl32 2. call InitCommonControlsEx and 3. a manifest. Right? So I guess you have it.
I'm not 100% but I think there is no need for duplicate code. All comctl32 needs to do is chain to the user32 classes, only overriding PAINT messages and some mouse events. So you don't have to reinvent the wheel.
Do you need lots of themed controls WM_PAINT code? Check out codeproject.com GUILIB project. They owner draw all windows controls with themes support.
Free Life Boaz
On 23.03.2005 13:04, Boaz Harrosh wrote:
Maybe it only register as per Process, which makes sense. And it does that before any window is displayed. Actually I know when. (A bug I had) it does it in the InitCommonControlsEx call. Not even in the DLLMain. An app that needs theming needs 3 things. 1. Link to comctl32 2. call InitCommonControlsEx and 3. a manifest. Right? So I guess you have it.
Sounds plausible. Reading a bit up on window classes on MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui...) indicates that overrideability of the default system classes is actually intended.
I'm not 100% but I think there is no need for duplicate code. All comctl32 needs to do is chain to the user32 classes, only overriding PAINT messages and some mouse events. So you don't have to reinvent the wheel.
Sounds feasible to me.
-f.r.
ok, further to what I mentioned before about RegisterUserApiHooks (and poking around in uxtheme.dll), I see the following things being hooked by uxtheme (at least it seems to be the complete list) GetScrollInfo SetScrollInfo EnableScrollBar SetWindowRgn DefWindowProcW DefWindowProcA PreWndProc (probobly stuff that happens internally before the window procedure gets called) PostWndProc (probobly stuff that happens internally after the window procedure gets called) PreDefDlgProc (probobly connected to dialog boxes) PostDefDlgProc (probobly connected to dialog boxes) GetSystemMetrics SystemParametersInfoA SystemParametersInfoW DrawFrameControl DrawCaption MDIRedrawFrame (probobly related to MDI frame windows)
Best guess is that RegisterUserApiHook and UnregisterUserApiHook are specifically provided so that uxtheme can override/hook code in user32.dll but at the same time if the themes service is disabled, none of the theming code kicks in. What probobly happens is that uxtheme.dll is loaded into every process (since even apps that know nothing about theming still get themed non-client areas etc AFAIK) which then hooks the user32 APIs to draw the themeing for the non-client areas. Then, theme-aware apps provide a manifest and link to the comctl32.dll 6.0 and from there get proper theming for all their standard (and common) controls.
Ordinal 34 (not given any external name by MS) in uxtheme.dll is what installs the user API hooks (what calls it I have no idea, probobly some system component, mabie the Theme service)
On 23.03.2005 13:25, Frank Richter wrote:
Sounds plausible. Reading a bit up on window classes on MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui...) indicates that overrideability of the default system classes is actually intended.
Hmm, for fun I just tried to simply re-register a standard control class on Wine, didn't work. I wonder if there's another way to replace/enhance a default class, preferably one that doesn't require arcane hooking or similar.
-f.r.
Boaz Harrosh wrote:
I'm not 100% but I think there is no need for duplicate code. All comctl32 needs to do is chain to the user32 classes, only overriding PAINT messages and some mouse events. So you don't have to reinvent the wheel.
Erm, it's not just the painting that needs to be overridden. The controls often need to be able to calculate their size
Do you need lots of themed controls WM_PAINT code? Check out codeproject.com GUILIB project. They owner draw all windows controls with themes support.
The interface to UxTheme is fairly straight-forward. The SDK sample "ThemeExplorer" is probably worth looking at.
Rob
On Wednesday 23 March 2005 07:04 am, Boaz Harrosh wrote:
Maybe it only register as per Process, which makes sense. And it does that before any window is displayed. Actually I know when. (A bug I had) it does it in the InitCommonControlsEx call. Not even in the DLLMain. An app that needs theming needs 3 things. 1. Link to comctl32 2. call InitCommonControlsEx and 3. a manifest. Right? So I guess you have it.
Part if the initialization happens for each process in InitCommonControlsEx However, the theme functions still do not work 100% in windows until after at least one window is created
There is also a "Themes" service that IIRC caches the theme data itself to share between processes and initialize some system-wide hooks
What I strongly suspect happens is this: 1.The themes service is always loaded and running and holds the theme data (and it contains details of which .msstyles file to use) 2.At some point (either at startup if the changes are global or when an app loads if the changes are app specific, I cant find where this bit happens but I suspect the themes service does this) control passes to ordinal 34 in uxtheme.dll (aka ThemeHooksInstall acording to uxtheme.pdb). This function calls an undocumented function in user32 called RegisterUserApiHooks (which appears to be taylor made for uxtheme to do what it needs to do). The function hooks: GetScrollInfo SetScrollInfo EnableScrollBar SetWindowRgn DefWindowProcW DefWindowProcA PreWndProc (probobly stuff that happens internally before the window procedure gets called) PostWndProc (probobly stuff that happens internally after the window procedure gets called) PreDefDlgProc (probobly connected to dialog boxes) PostDefDlgProc (probobly connected to dialog boxes) GetSystemMetrics SystemParametersInfoA SystemParametersInfoW DrawFrameControl DrawCaption MDIRedrawFrame (probobly related to MDI frame windows) This is what causes all apps (including non-theme-aware ones) to get themed non-client areas (window borders etc) 3.Apps that are theme aware have a manifest, load comctl32.dll 6.0 and probobly have to call InitCommonControlsEx (although I think some of the code in the dllmain for comctl32.dll 6.0 may also end up calling InitCommonControlsEx). This causes new versions of the stock classes (button, list box, edit, combo box etc etc etc) to be created and registered. A cursory examination of some of these classes shows that they dont seem to "pull code" from the stock implementation in user32.dll (i.e. anything they dont themselves handle goes back to DefWindowProc). In particular, it doesnt appear as though they have any knowledge of the classes or window procedures contained in user32.dll. then 4.Apps that need to do something extra call into functions exported by uxtheme.dll to do whatever they need to do.
user32.dll seems to have no knowledge whatsoever about themeing and uxtheme. All that user32 has is RegisterUserApiHooks (and the matching UnregisterUserApiHooks) that uxtheme uses to hook into user32.dll and do stuff.
Exactly how the theme service and theme engine works "under the hood" doesnt matter. But for ReactOS and WINE purposes, I suggest we implement the following: 1.A function similar to RegisterUserApiHooks/UnregisterUserApiHooks (either reverse engineer the MS function or write our own). This will allow uxtheme to hook into the global drawing for things like window borders without user32 needing to care about uxtheme and what uxtheme does (just like how MS hooks into user32 that way) 2.Whatver code is necessary to get the hooks installed right so that all apps get the "global" theming like on real windows 3.Support to read the manifest and load a new comctl32.dll that would be like the version 6 from microsoft (and would contain complete theme-aware implementations of the stock controls just like MS comctl32.dll 6.0 does) and 4.All the needed uxtheme exports to make stuff run
This would be the same way Microsoft does things. User32.dll would have no idea whatsoever about uxtheme and theming All apps would get non-client-area themeing like on windows. And only theme aware apps would get themed controls etc (the rest would get "stock" windows controls)
Oh and btw, if this "reverse engineering" is not "clean room" enough for WINE and ReactOS, let me know and I will stop posting it :)
Also related to this (as pointed out in IRC) is Activation Contexts/SxS stuff), we need this to make sure the correct window classes are used at the correct time.
Jonathan Wilson wrote:
Exactly how the theme service and theme engine works "under the hood" doesnt matter. But for ReactOS and WINE purposes, I suggest we implement the following: 1.A function similar to RegisterUserApiHooks/UnregisterUserApiHooks (either reverse engineer the MS function or write our own). This will
I really don't like the way you're going about figuring these things out. It seems to me like you're disassembling and reading assembly the Microsoft DLLs, as you've done in the past (your cards.dll "implementation"). This bars you from them reimplementing them, IMO.
Please don't post stuff like this to wine-devel. Reading descriptions on MSDN and writing test programs should be sufficient for figuring out how Windows works.
Mike
What I am doing here is clean-room reverse engineering. Essentially it involves taking existing binary modules and sources of information and writing up what they do in a way that isnt violating the copyright on the origonal (IANAL but I dont think what I posted violates the copyright on the windows binaries). Then it involves someone else who hasnt seen the origonal copyrighted source using the resulting information to re-implement whatever the information describes.
As long as the person who origonally did the reverse engineering never contributes anything to the resulting code, it is (AFAIK, IAMAL) perfectly legal (after all, this is exactly what was done when the first clone PC bios was written, one group disassembled the origonal IBM BIOS and wrote up documents on how it works and how to talk to it. Then another group not connected to the people who did the origonal reverse engineering took the documentation and re-implemented the BIOS from just the documentation without looking at the orgininal IBM implementation)
I never had any plans to actually write code for this (since doing so is out of my skill range) and as long as I never do so in the future (thus "tainting" the code I write as being a potential Derived Work of the microsoft code I looked at), I dont see any way that the results of this investigation could be considered a derived work of any microsoft code.
Although if I have a mis-understanding of this situation, please point out what I am doing that would make code written by someone else using the information in my posts a Derived Work of microsofts origonal binaries.
Jonathan Wilson wrote:
What I am doing here is clean-room reverse engineering.
There's no reason that we need to expose ourselves to any legal risk at all. It may be your opinion that reading assembly code and describing it is legal and safe, but I don't agree and I'm sure others who work on Wine don't either.
The original IBM BIOS was clean room reverse engineered because there was not enough documentation available for it. We have MSDN, which is not 100% complete, but is good enough for most purposes. Other things can be deduced from test programs. Information that cannot be deduced by a test program is irrelevant.
Reverse engineering does not help Wine. Casual observers will assume that Wine is the result of reverse engineering by disassembly, which is incorrect and harmful.
Mike
In copyright law it's the result that matter, not the process. To be protected by copyright law, it must be in tangible form. Looking at disassembled code is permitted by copyright law so it's only a problem if the person doing it lacks self-discipline and uses the disassembled code in a way that violates copyright law.
That said, I don't believe there is a need for reverse engineering methods for implementing the majority of ReactOS and WINE. Our goal is to run Windows software on ReactOS and other free operating systems. We have some smart people on these projects. If the Windows software vendors could figure out how to use the interfaces using the public available documentation, then we can certainly implement the interfaces from that same information. If there is an interface that isn't documented, then certainly most Windows software won't use it and there is no need to implement the interface at all.
Casper
References:
From http://www.nus.edu.sg/intro/slides/021111_1_Wilson%20Wong.ppt
What is protectable?
Functionality? - not protected - must be an "expression...of a set of instructions" - Autodesk Inc v Dyason (Aust): copying function of AutoCAD lock but not code (no infringement)
Program Structure? - (cf: plot elements in literary/dramatic works capable of protection) - eg. structural arrangements of modules and subroutines - yes if expression of idea, & no if ideas or functions: difficult line to draw - yes if organisation, sequence, arrangement or compilation - not protectable: elements of software which are: * ideas; * dictated by efficiency or external factors (eg h/w) specs, compatibility reqms, industry standards; or * public domain - not if similarity is due only to similar subject matter * analogy: drawing of a hand * eg any 2 word processors will have some structural similarities
-----Original Message----- From: wine-devel-admin@winehq.org [mailto:wine-devel-admin@winehq.org] On Behalf Of Mike McCormack Sent: 25. marts 2005 10:39 To: Jonathan Wilson Cc: wine-devel@winehq.org; ros-dev@reactos.com Subject: Re: I think I know how uxtheme works...
Jonathan Wilson wrote:
What I am doing here is clean-room reverse engineering.
There's no reason that we need to expose ourselves to any legal risk at all. It may be your opinion that reading assembly code and describing it is legal and safe, but I don't agree and I'm sure others who work on Wine don't either.
The original IBM BIOS was clean room reverse engineered because there was not enough documentation available for it. We have MSDN, which is not 100% complete, but is good enough for most purposes. Other things can be deduced from test programs. Information that cannot be deduced by a test program is irrelevant.
Reverse engineering does not help Wine. Casual observers will assume that Wine is the result of reverse engineering by disassembly, which is incorrect and harmful.
Mike
On 22.03.2005 17:00, Alexandre Julliard wrote:
Then the first thing to do is to figure out exactly how Windows does it, and do it the same way.
To roughly recapitulate: Windows seems to do the theming in the implementation of the standard controls - with the twist that comctl32.dll v6 contains copies of that controls which are used when theming is enabled instead the user implementations... or did I miss something?
-f.r.
On Tue, 22 Mar 2005 16:22:25 +0800, Dmitry Timoshkov wrote:
user32 can not depend on uxtheme or any other high level dll.
Hmm, why not? For DLLs that can be recompiled and used on Windows this policy makes sense but our user32 cannot be, so I do not see what we would lose by having this.
The alternative is to copy/paste the code into comctl32 which is what Microsoft appear to have done, and I know we don't want to do that ...
thanks -mike
"Mike Hearn" mike@navi.cx wrote:
user32 can not depend on uxtheme or any other high level dll.
Hmm, why not? For DLLs that can be recompiled and used on Windows this policy makes sense but our user32 cannot be, so I do not see what we would lose by having this.
It creates circular dependencies and an impossibility to correctly start up Wine. Imagine for a moment that ntdll depends on foo.dll which in turn imports kernel32.
On 22.03.2005 15:12, Dmitry Timoshkov wrote:
It creates circular dependencies and an impossibility to correctly start up Wine. Imagine for a moment that ntdll depends on foo.dll which in turn imports kernel32.
Maybe that can be worked around by having user32.dll load uxtheme.dll lazily... This way, when uxtheme.dll is loaded, user32.dll should be loaded and useable by uxtheme.dll. If for some reason uxtheme can't be loaded, no problem either, you just don't get theming.
Apparently, Wine does handle that circularity quite well. I guess as long as you don't call uxtheme code from the user32 DLL init code and/or vice versa things should work.
-f.r.
Frank Richter wrote:
On 22.03.2005 15:12, Dmitry Timoshkov wrote:
It creates circular dependencies and an impossibility to correctly start up Wine. Imagine for a moment that ntdll depends on foo.dll which in turn imports kernel32.
Maybe that can be worked around by having user32.dll load uxtheme.dll lazily... This way, when uxtheme.dll is loaded, user32.dll should be loaded and useable by uxtheme.dll. If for some reason uxtheme can't be loaded, no problem either, you just don't get theming.
Apparently, Wine does handle that circularity quite well. I guess as long as you don't call uxtheme code from the user32 DLL init code and/or vice versa things should work.
+1
Doing a dump of the imports table from native uxtheme.dll from my XPSP2 box, I see that it imports a function from user32.dll called RegisterUserApiHook which is totally undocumented (neither MSDN or google show up any info about what it does). This function is only present in Windows XP (and I assume Server 2003 which also has uxtheme). Based on the name, I suspect that it is a function that lets uxtheme hook user32 api calls (without documentation or code to that function, I cant really say anything more)
Frank Richter wrote:
Hi, to see how easy (or not) it would be to make the controls use themes, I tried to get themed buttons; the result is the attached patch (to try it out, you need an .msstyles file and appropriate registry setup). It's probably not perfect as it is, comments/questions are welcome.
Index: dlls/user/Makefile.in
RCS file: /home/wine/wine/dlls/user/Makefile.in,v retrieving revision 1.88 diff -u -r1.88 Makefile.in --- dlls/user/Makefile.in 10 Mar 2005 15:47:53 -0000 1.88 +++ dlls/user/Makefile.in 21 Mar 2005 18:46:31 -0000
- case WM_THEMECHANGED:
- theme = get_button_theme( hWnd );
- if ( theme != NULL )
CloseThemeData ( theme );
- theme = OpenThemeData( hWnd, themeClass );
- set_button_theme( hWnd, theme );
- break;
Where you using a native theme DLL or the builtin one? If native which one where you using? How did you Isolate it, I mean how many dll's, files, and registry is it.
Free Life Boaz
On 22.03.2005 09:35, Boaz Harrosh wrote:
Where you using a native theme DLL or the builtin one? If native which one where you using? How did you Isolate it, I mean how many dll's, files, and registry is it.
If you mean with "Theme DLL" the uxtheme.dll, that is the builtin one.
If you mean the DLL with the Theme resources (in other words, the .msstyles file), that's the Luna.msstyles from a WinXP SP2. It doesn't depend on any other external resources/DLLs/etc. In terms of registry settings, it's just the stuff needed to have the builtin uxtheme working and activated:
[HKEY_USERS\res\Software\Microsoft\Windows\CurrentVersion\ThemeManager] "ColorName"="Metallic" "DllName"="c:\Luna.msstyles" "SizeName"="NormalSize" "ThemeActive"="1"
-f.r.