Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Scrollbars on WinXP.

14 views
Skip to first unread message

Oscar Fuentes

unread,
Jun 16, 2007, 9:39:05 AM6/16/07
to
Hi!

On a WinXP machine, this code:

scrollbar .s
pack .s -fill both -expan true

creates a xp-style scrollbar when executed on wish. However, when
executed on my application (which embeds tcl/tk), it creates an
old-style scrollbar.

I can't figure out the cause. My app uses the libraries on the
ActiveState 8.4.13 installment where wish resides.

(BTW, I've asked a similar question two weeks ago. Not only was it
ignored by Those Who Know, but by the Orphans of the Week section on
TclURL, which makes me feel a bit excluded :-)

--
Oscar

Gerald W. Lester

unread,
Jun 16, 2007, 2:04:16 PM6/16/07
to

I do not remember seeing such a post.

--
+--------------------------------+---------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

Uwe Klein

unread,
Jun 16, 2007, 2:35:22 PM6/16/07
to
My apology for that omission, I will mention it in the next ( sunday night )
TclUrl.

I have no good idea why this happens.
could there be some magic in init.tcl?

uwe

Oscar Fuentes

unread,
Jun 16, 2007, 3:33:20 PM6/16/07
to
Uwe Klein <uwe_klein_...@t-online.de> writes:

> Oscar Fuentes wrote:
>> Hi!
>>
>> On a WinXP machine, this code:
>>
>> scrollbar .s
>> pack .s -fill both -expan true
>>
>> creates a xp-style scrollbar when executed on wish. However, when
>> executed on my application (which embeds tcl/tk), it creates an
>> old-style scrollbar.
>>
>> I can't figure out the cause. My app uses the libraries on the
>> ActiveState 8.4.13 installment where wish resides.
>>
>> (BTW, I've asked a similar question two weeks ago. Not only was it
>> ignored by Those Who Know, but by the Orphans of the Week section on
>> TclURL, which makes me feel a bit excluded :-)
>>
> My apology for that omission, I will mention it in the next ( sunday
> night ) TclUrl.

Thanks!

> I have no good idea why this happens. could there be some magic in
> init.tcl?

init.tcl does not mention scrollbar. Besides, it is always loaded,
right? (Wish and my app both fails to start if I break init.tcl) What
kind of "magic" could produce the difference I describe above?

--
Oscar

Oscar Fuentes

unread,
Jun 16, 2007, 3:35:44 PM6/16/07
to
"Gerald W. Lester" <Gerald...@cox.net> writes:

> Oscar Fuentes wrote:
>> Hi!
>>
>> On a WinXP machine, this code:
>>
>> scrollbar .s
>> pack .s -fill both -expan true
>>
>> creates a xp-style scrollbar when executed on wish. However, when
>> executed on my application (which embeds tcl/tk), it creates an
>> old-style scrollbar.
>>
>> I can't figure out the cause. My app uses the libraries on the
>> ActiveState 8.4.13 installment where wish resides.
>>
>> (BTW, I've asked a similar question two weeks ago. Not only was it
>> ignored by Those Who Know, but by the Orphans of the Week section on
>> TclURL, which makes me feel a bit excluded :-)
>
> I do not remember seeing such a post.

You can read it here:

http://groups.google.com/group/comp.lang.tcl/msg/110518d84acae358

--
Oscar

Uwe Klein

unread,
Jun 16, 2007, 5:22:39 PM6/16/07
to
Oscar Fuentes wrote:

> init.tcl does not mention scrollbar. Besides, it is always loaded,
> right? (Wish and my app both fails to start if I break init.tcl) What
> kind of "magic" could produce the difference I describe above?
>

windows is something i prod with a very long stick.
Let's see what others have to contribute.

uwe

Georgios Petasis

unread,
Jun 17, 2007, 3:45:11 AM6/17/07
to Oscar Fuentes
O/H Oscar Fuentes έγραψε:

It all depends on how you embed tcl/tk in your app. The same will happen
if you start tclsh and do a package require Tk (again scrollbars will
not use the xp theme).
My personal opinion is that this is a bug in Tk. But if you post how you
embed Tk in your app, I can provide some more help on how tp fix this :-)

George

Oscar Fuentes

unread,
Jun 17, 2007, 4:31:05 AM6/17/07
to
Georgios Petasis <pet...@iit.demokritos.gr> writes:

Hello George.

This is the code I use to init tcl/tk:

#if defined(_WIN32)
# include <windows.h>
#endif

#include <tcl.h>
#include <tk.h>

// Other #include's here, unrelated to tcl.

Tcl_Interp *interp = 0;

int InitTclTk(int argc, char **argv) {
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
// if (Tcl_InitStubs(interp, TCL_VERSION, 1) == NULL)
// abort();

if( Tcl_Init(interp) == TCL_ERROR || Tk_Init(interp) == TCL_ERROR ) {
NotifyException( Tcl_GetStringResult(interp), 31 );
/* we won't reach this, but we need the return */
return TCL_ERROR;
}
else {
Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
return TCL_OK;
}
}

It's C++. Tcl is linked as a dll (the same wish.exe does). I'm using
MSVC++ 7.1.

There is no %HOME%/wishrc.tcl.

I see no substantial difference with what wish does for initiating Tcl
and Tk.

I hope this is the information you need.

Regards,

--
Oscar

Georgios Petasis

unread,
Jun 17, 2007, 6:19:35 AM6/17/07
to Oscar Fuentes
Actually, the whole issue is whether InitCommonControlsEx has been
called. This is performed in TkWinXInit(HINSTANCE hInstance) (file
win/tkWinX.c), which is called by TkpInit(Tcl_Interp *interp) (file
win/tkWinInit.c) through:

TkWinXInit(Tk_GetHINSTANCE());

which in turn is called by Initialize(Tcl_Interp *interp) (file
generic/tkWindow.c), which is called from Tk_Init :-)

The fact that you are not getting xp scrollbars means that
InitCommonControlsEx must has somehow failed. Can you try
calling yourself InitCommonControlsEx and examine the returned error?
From TkWinXInit:

INITCOMMONCONTROLSEX comctl;
ZeroMemory(&comctl, sizeof(comctl));
bool loaded = InitCommonControlsEx(&comctl);

Does the InitCommonControlsEx returns true?

George

O/H Oscar Fuentes έγραψε:

Oscar Fuentes

unread,
Jun 17, 2007, 8:20:48 AM6/17/07
to Georgios Petasis
Georgios Petasis <pet...@iit.demokritos.gr> writes:

> Actually, the whole issue is whether InitCommonControlsEx has been
> called. This is performed in TkWinXInit(HINSTANCE hInstance) (file
> win/tkWinX.c), which is called by TkpInit(Tcl_Interp *interp) (file
> win/tkWinInit.c) through:
>
> TkWinXInit(Tk_GetHINSTANCE());
>
> which in turn is called by Initialize(Tcl_Interp *interp) (file
> generic/tkWindow.c), which is called from Tk_Init :-)
>
> The fact that you are not getting xp scrollbars means that
> InitCommonControlsEx must has somehow failed. Can you try
> calling yourself InitCommonControlsEx and examine the returned error?
> From TkWinXInit:
>
> INITCOMMONCONTROLSEX comctl;
> ZeroMemory(&comctl, sizeof(comctl));
> bool loaded = InitCommonControlsEx(&comctl);
>
> Does the InitCommonControlsEx returns true?

George,

Your code returns 0. It does so no matter where I put it (before or
after the initialization of tcl/tk, tried just in case).

Thanks for your attention.

--
Oscar

Georgios Petasis

unread,
Jun 17, 2007, 9:04:06 AM6/17/07
to Oscar Fuentes
O/H Oscar Fuentes έγραψε:

This means that you are not going to get xp scrollbars until
InitCommonControlsEx returns true :-) Its not a tcl/tk issue, but rather
an issue of how you build your application (or windows internals?). I
would suggest:

a) Try to add a manifest file to your dll.

b) Try to compile your code on an XP machine, using a VC++ version no
earlier than 6.

c) Try to call InitCommonControlsEx not only in your dll, but also in
the application that loads this dll.

d) Try to build a small application that calls only InitCommonControlsEx
:-) and see how you can compile it to get InitCommonControlsEx to return
true...

Actually, you have to find out why InitCommonControlsEx fails (can you
retrieve and print the error message InitCommonControlsEx saves?).
And if everything fails, you can always try to use the tile package
(which draws the widgets directly, so it does not depend on getting
InitCommonControlsEx to work...)

George

Oscar Fuentes

unread,
Jun 17, 2007, 9:45:29 AM6/17/07
to Georgios Petasis
Georgios Petasis <pet...@iit.demokritos.gr> writes:

>> Your code returns 0. It does so no matter where I put it (before or
>> after the initialization of tcl/tk, tried just in case).
>>
>> Thanks for your attention.
>>
>
> This means that you are not going to get xp scrollbars until
> InitCommonControlsEx returns true :-) Its not a tcl/tk issue, but
> rather an issue of how you build your application

This is puzzling, as my application is as common as it can be, on each
and every aspect (build method, tcl/tk embbedding, etc).

> (or windows
> internals?). I would suggest:
>
> a) Try to add a manifest file to your dll.

Yes, after adding a manifest, I obtain winxp style scrollbars.

> b) Try to compile your code on an XP machine, using a VC++ version no
> earlier than 6.

Using 7.1 here.

> c) Try to call InitCommonControlsEx not only in your dll, but also in
> the application that loads this dll.

The test you suggested was performed on a .exe.

> d) Try to build a small application that calls only
> InitCommonControlsEx :-) and see how you can compile it to get
> InitCommonControlsEx to return true...

Good idea. I'll try it.

> Actually, you have to find out why InitCommonControlsEx fails (can you
> retrieve and print the error message InitCommonControlsEx saves?).

The MSDN documentation for InitCommonControlsEx says nothing about
extended error info, it just says that returns false in when it
fails. I've confirmed that GetLastError() is unaffected. See

http://msdn2.microsoft.com/en-us/library/ms672653.aspx

On the same page some users report that InitCommonControlsEx is
required even if you use a manifest, but that's not my case.

> And if everything fails, you can always try to use the tile package
> (which draws the widgets directly, so it does not depend on getting
> InitCommonControlsEx to work...)

Some people is writing tile-related code assuming that tk's scrollbars
looks modern on winxp. This is the case for widget::scrolledwindow
(from tklib) where it checks if the platform is x11 and then (and only
then) uses tile's scrollbar.

Thank you very much for your help, George.

--
Oscar

Roy Terry

unread,
Jun 17, 2007, 11:25:16 AM6/17/07
to
Oscar Fuentes wrote:
> Hi!
>
> On a WinXP machine, this code:
>
> scrollbar .s
> pack .s -fill both -expan true
>
> creates a xp-style scrollbar when executed on wish. However, when
> executed on my application (which embeds tcl/tk), it creates an
> old-style scrollbar.
>
> I can't figure out the cause. My app uses the libraries on the
> ActiveState 8.4.13 installment where wish resides.
This is not a problem I've seen before. I would start by
reviewing all the Windows Properties of the executable in which
you're embedding Tcl/Tk. Compare those (build, link, etc) parameters
with the standard wish.exe and see if any differences pop up.

Oscar Fuentes

unread,
Jun 17, 2007, 11:36:58 AM6/17/07
to

Hello Roy.

Roy Terry <r...@terryhome.org> writes:

> Oscar Fuentes wrote:
>> Hi!
>>
>> On a WinXP machine, this code:
>>
>> scrollbar .s
>> pack .s -fill both -expan true
>>
>> creates a xp-style scrollbar when executed on wish. However, when
>> executed on my application (which embeds tcl/tk), it creates an
>> old-style scrollbar.
>>
>> I can't figure out the cause. My app uses the libraries on the
>> ActiveState 8.4.13 installment where wish resides.
> This is not a problem I've seen before. I would start by
> reviewing all the Windows Properties of the executable in which
> you're embedding Tcl/Tk. Compare those (build, link, etc) parameters
> with the standard wish.exe and see if any differences pop up.

What are the "Windows Properties" and how can I inspect them?

--
Oscar

Georgios Petasis

unread,
Jun 17, 2007, 12:13:48 PM6/17/07
to Oscar Fuentes
I am glad that the problem was fixed by simply adding a manifest file!
There is no need to check further the issue. Just add a manifest file in
your dll and then Tk will be able to call InitCommonControlsEx
sucessfully, so you will not have to call InitCommonControlsEx yourself.

George

O/H Oscar Fuentes έγραψε:

Alexandre Ferrieux

unread,
Jun 17, 2007, 12:33:43 PM6/17/07
to
On Jun 17, 6:13 pm, Georgios Petasis <peta...@iit.demokritos.gr>
wrote:

> I am glad that the problem was fixed by simply adding a manifest file!
> There is no need to check further the issue. Just add a manifest file in
> your dll and then Tk will be able to call InitCommonControlsEx
> sucessfully, so you will not have to call InitCommonControlsEx yourself.
>

Hi George,

For the rest of us who are not Windows-literate, can you give a
pointer to a *concise* description of what a manifest is, when to use
one, what routines or behavior its affects, etc ? Googling brought up
only very vague comments of huge MS bloat-doc...

TIA,

-Alex

Georgios Petasis

unread,
Jun 17, 2007, 2:47:44 PM6/17/07
to Alexandre Ferrieux
O/H Alexandre Ferrieux έγραψε:

Well, I am also windows-agnostic :-), as I primarily write my code in
linux and I simply compile it to get it run also under windows.
However, the problem in this case was the following:
Tk under windows uses the native widgets offered by the platform, and
not the implementation used under unix. Now, when you want to use these
widgets, you must call InitCommonControlsEx, which loads a dll that
implements these "common controls". The problem is that under the
various windows releases, there are so many versions of the needed dlls
lying in a typical windows installations. When XP got released (which
added a new version of these dlls), microsoft introduced a way for an
executable to declare a "preference" of a "wanted" dll version to the OS
runtime linker: this way is through an xml file known as a "manifest"
file. So, this manifest file (which can be either embedded in the
app/dll or be in the same directory as the application/dll) simply
declares the minimum versions of the dlls the app wants. In systems that
understand this manifest files (XP & newer), the runtime linker will
load the correct versions of the dll.

For example, to get the XP themed common controls, you need at least
version 6 of the common controls dll. This is why Tk's wish has a
manifest file similar to:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="@TK_WIN_VERSION@"
processorArchitecture="@MACHINE@"
name="Tcl.Tk.wish"
type="win32"
/>
<description>Tcl/Tk windowing shell (wish)</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="@MACHINE@"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

So, when wish runs under XP, at least version 6 of the dll will be
loaded, and thus we get the xp themed scrollbars. But if the manifest
file is missing (as was the case of the original poster of the thread)
an earlier version of the dll was loaded under XP, which offers windows
95 themed widgets...

For tk programs/programs that embed tk this manifest file must exist to
get the xp scrollbars. This manifest file need not be anything complex,
just a modified version of the tk's manifest file will do.

I am not sure, but I think that tclsh.exe does not have this manifest
file embedded, and I think that this is why you don't get xp themed
scrollbars when tk gets loaded through package require in it...

To sum up, you need a manifest file when you want to use a dll of a
specific version (or newer), because you want to use some functionality
that does not exist in earlier versions (i.e. you want to use a specific
version of the VC++ runtime). Recent versions of VC++ automatically
generate a manifest file for such common dlls when you compile an app
(but they don't actually embed them in the app). In practice, I only
needed manifest files only to get xp themes in tk-embedding apps :-)

(And no, manifest files have nothing to do with tile: tile does not use
at all "common controls" like the windows tk scrollbar. Tile directly
loads the uxtheme.dll and draws the widgets using the proper API - and
which fortunately works also under vista :-) )

George

Georgios Petasis

unread,
Jun 17, 2007, 2:52:00 PM6/17/07
to Oscar Fuentes
O/H Oscar Fuentes έγραψε:

>
> Some people is writing tile-related code assuming that tk's scrollbars
> looks modern on winxp. This is the case for widget::scrolledwindow
> (from tklib) where it checks if the platform is x11 and then (and only
> then) uses tile's scrollbar.
>
> Thank you very much for your help, George.
>
Well I consider this a bug :-)
And I would like very much to see bwidgets use tile (at least the
ScrolledWindow widget), which looks ok under xp, but looks very bad
under linux with tile+tileqt :-(

But I understand that the conversion of bwidgets to use tile is not an
easy task as bwidgets rely heavily on the configuration options used by
tk but not by tile...

George

Alexandre Ferrieux

unread,
Jun 17, 2007, 3:18:30 PM6/17/07
to
On Jun 17, 8:47 pm, Georgios Petasis <peta...@iit.demokritos.gr>
wrote:
>
> [nice and clear picture of Windows's "manifest" files]

Thanks George: excellent !
Maybe you should:
1) Add this on the wiki
2) TIP for inclusion of the necessary, minimal, manifest in tclsh.

Best regards,

-Alex

Oscar Fuentes

unread,
Jun 17, 2007, 3:58:02 PM6/17/07
to
Georgios Petasis <pet...@iit.demokritos.gr> writes:

> O/H Oscar Fuentes έγραψε:
>>
>> Some people is writing tile-related code assuming that tk's scrollbars
>> looks modern on winxp. This is the case for widget::scrolledwindow
>> (from tklib) where it checks if the platform is x11 and then (and only
>> then) uses tile's scrollbar.
>>
>> Thank you very much for your help, George.
>>
> Well I consider this a bug :-)
> And I would like very much to see bwidgets use tile (at least the
> ScrolledWindow widget), which looks ok under xp, but looks very bad
> under linux with tile+tileqt :-(

Just in case there is a misunderstanding, I'm not talking about
BWidgets, but about tklib's widget::* set of megawidgets:

http://tcllib.sourceforge.net/doc/widget.html

They state:

This package provides megawidgets based on the snit oo system
(snidgets). It makes use of the Tile/Ttk themed widget set.

However, for widget::scrolledwindow (not to confuse with BWidget's
ScrolledWindow), they explicitly avoid Tile if not running on X, so tk
scrollbars are used in other platforms. I've filled a bug report about
this, but they closed it saying that tk's scrollbar looks the same as
Tile's under winxp. I'm afraid they doesn't know about the manifest
requirement. It's one more file to distribute and embedding it into
the executable is a nuisance:

http://blogs.msdn.com/nikolad/articles/425359.aspx

BTW, I support Alex's request for including your explanation of
manifest files in the wiki. It's very clear and well written.

[snip]

Regards,

--
Oscar

Georgios Petasis

unread,
Jun 17, 2007, 4:48:47 PM6/17/07
to Oscar Fuentes
O/H Oscar Fuentes έγραψε:

> Georgios Petasis <pet...@iit.demokritos.gr> writes:
>
>> O/H Oscar Fuentes έγραψε:
>>> Some people is writing tile-related code assuming that tk's scrollbars
>>> looks modern on winxp. This is the case for widget::scrolledwindow
>>> (from tklib) where it checks if the platform is x11 and then (and only
>>> then) uses tile's scrollbar.
>>>
>>> Thank you very much for your help, George.
>>>
>> Well I consider this a bug :-)
>> And I would like very much to see bwidgets use tile (at least the
>> ScrolledWindow widget), which looks ok under xp, but looks very bad
>> under linux with tile+tileqt :-(
>
> Just in case there is a misunderstanding, I'm not talking about
> BWidgets, but about tklib's widget::* set of megawidgets:
>
> http://tcllib.sourceforge.net/doc/widget.html
>
> They state:
>
> This package provides megawidgets based on the snit oo system
> (snidgets). It makes use of the Tile/Ttk themed widget set.
>
> However, for widget::scrolledwindow (not to confuse with BWidget's
> ScrolledWindow), they explicitly avoid Tile if not running on X, so tk
> scrollbars are used in other platforms. I've filled a bug report about
> this, but they closed it saying that tk's scrollbar looks the same as
> Tile's under winxp.
This assumes that tile users under windows always use the xpnative
theme, which may be not true. Why not to propose a tile version of the
widget that uses always tile?

I'm afraid they doesn't know about the manifest
> requirement. It's one more file to distribute and embedding it into
> the executable is a nuisance:
>
> http://blogs.msdn.com/nikolad/articles/425359.aspx

If you use the tk scrolbar, tk offers no way to check whether a themed
one is used, or not.


>
> BTW, I support Alex's request for including your explanation of
> manifest files in the wiki. It's very clear and well written.

:-)

>
> [snip]
>
> Regards,
>

Yes, I understood that you were talkin about tklib's widget. But I
usually use ScrolledWindow and not tklib's widget (I think bwidget's one
works better :-( )

George

Oscar Fuentes

unread,
Jun 17, 2007, 5:22:19 PM6/17/07
to
Georgios Petasis <pet...@iit.demokritos.gr> writes:

> If you use the tk scrolbar, tk offers no way to check whether a themed
> one is used, or not.

Very good point. I've added it to SourceForge issue # 1738192. Thanks!

[snip]

--
Oscar

Jeff Hobbs

unread,
Jun 18, 2007, 4:02:28 PM6/18/07
to Georgios Petasis, Oscar Fuentes
Georgios Petasis wrote:
> I am glad that the problem was fixed by simply adding a manifest file!
> There is no need to check further the issue. Just add a manifest file in
> your dll and then Tk will be able to call InitCommonControlsEx
> sucessfully, so you will not have to call InitCommonControlsEx yourself.

I would like to see clarification, because I believe that adding the
manifest file to your dll is not sufficient - it must be added to the
exe in which you embed Tcl. I have tried the pure DLL approach and it
never seemed to work (would be nice ...).

Jeff

Oscar Fuentes

unread,
Jun 18, 2007, 4:17:37 PM6/18/07
to
Jeff Hobbs <je...@activestate.com> writes:

> Georgios Petasis wrote:
>> I am glad that the problem was fixed by simply adding a manifest file!
>> There is no need to check further the issue. Just add a manifest
>> file in your dll and then Tk will be able to call
>> InitCommonControlsEx sucessfully, so you will not have to call
>> InitCommonControlsEx yourself.
>
> I would like to see clarification, because I believe that adding the
> manifest file to your dll is not sufficient - it must be added to the
> exe in which you embed Tcl. I have tried the pure DLL approach and it
> never seemed to work (would be nice ...).

Just to clarify: I created a manifest with the same name as the exe
and it worked. Never tried with dlls.

OTOH, a manifest is not mandatory for InitCommonControlsEx to success:

INITCOMMONCONTROLSEX comctl;
comctl.dwSize = sizeof(comctl);
comctl.dwICC = ICC_WIN95_CLASSES;// | ICC_STANDARD_CLASSES;
SetLastError(0);
bool loaded = InitCommonControlsEx(&comctl);
fprintf(stderr, "Loaded: %d LastError: %d\n", loaded, GetLastError());

This works (George's test code was wrong) But it fails when you uncomment
the ICC_STANDARD_CLASSES part, which is, AFAIK, the flag needed to
activate the winxp style controls. It fails too (with
ICC_STANDARD_CLASSES) when a manifest exists.

--
Oscar

0 new messages