summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormdejong <mdejong>2004-09-23 00:56:13 (GMT)
committermdejong <mdejong>2004-09-23 00:56:13 (GMT)
commite28dfd1c3d87b330019333b13db44d6ec89016bc (patch)
treea5ef654dd2cffd06d968ff35befb088f3e4a8054
parent1df83bcde28bf0df5b71b229e0b1c2fbfa2ab183 (diff)
downloadtk-e28dfd1c3d87b330019333b13db44d6ec89016bc.zip
tk-e28dfd1c3d87b330019333b13db44d6ec89016bc.tar.gz
tk-e28dfd1c3d87b330019333b13db44d6ec89016bc.tar.bz2
* generic/tkInt.decls: Add decl for TkWinGetPlatformTheme.
It is only defined under Win32. * generic/tkIntPlatDecls.h: Regen. * generic/tkStubInit.c: Regen. * win/tkWinInt.h: Define TK_THEME_WIN_CLASSIC and TK_THEME_WIN_XP. * win/tkWinMenu.c (DrawMenuEntryAccelerator, DrawMenuEntryLabel): Draw a disabled 3D text highlight for the accelerator only with the Win95/98 look. Same goes for the menu entry text. * win/tkWinX.c (TkWinGetPlatformId, TkWinGetPlatformTheme): Automatically detect the Windows theme in use and return either TK_THEME_WIN_CLASSIC or TK_THEME_WIN_XP when the TkWinGetPlatformTheme function is invoked. [Patch 866194] * win/tkWinMenu.c: only provide a submenu handle when the MF_POPUP flag is given, fixing a recently-introduced crash when submenus are disabled. Also better error checking for this sort of situation in the future. * win/tkWinMenu.c (ReconfigureWindowsMenu): Fix drawing of a disabled (TkWinHandleMenuEvent, DrawMenuEntryArrow): cascade menu arrow. Tk was displaying a disabled cascade menu arrow in black instead of gray. This was caused by a bug in the Win32 code for user drawn menu items. The fix is to avoid telling Windows that the menu item is a cascade type and then draw the gray arrow bitmap on our own. [Patch 865842] * win/tkWinMenu.c (DrawWindowsSystemBitmap): Fix a strange Win32 bug where the logical coordinates returned by a call to DPtoLP are wrong the first time a menu is posted. This bug manifested itself by drawing the bitmap in the wrong place in a menu. The fix was to pass the newly created DC instead of the DC from the window. * win/tkWinMenu.c (DrawMenuEntryAccelerator): (DrawMenuEntryLabel): When drawing the label text and accelerator text for a disabled menu entry be sure to draw a 3D highlight. The only exception to this is when a disabled menu entry is highlighted, in that case do not draw a 3D hightlight. * win/tkWinMenu.c (DrawMenuEntryAccelerator, DrawMenuEntryArrow): Move the unused menu arrow drawing code in DrawMenuEntryAccelerator into a new function named DrawMenuEntryArrow. This makes no functional change but it will make it easier to fix things in the future.
-rw-r--r--ChangeLog58
-rw-r--r--generic/tkInt.decls6
-rw-r--r--generic/tkIntPlatDecls.h9
-rw-r--r--generic/tkStubInit.c3
-rw-r--r--win/tkWinInt.h8
-rw-r--r--win/tkWinMenu.c191
-rw-r--r--win/tkWinX.c57
7 files changed, 278 insertions, 54 deletions
diff --git a/ChangeLog b/ChangeLog
index 85c37a6..3eb4d79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,63 @@
2004-09-22 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tkInt.decls: Add decl for TkWinGetPlatformTheme.
+ It is only defined under Win32.
+ * generic/tkIntPlatDecls.h: Regen.
+ * generic/tkStubInit.c: Regen.
+ * win/tkWinInt.h: Define TK_THEME_WIN_CLASSIC and
+ TK_THEME_WIN_XP.
+ * win/tkWinMenu.c (DrawMenuEntryAccelerator, DrawMenuEntryLabel):
+ Draw a disabled 3D text highlight for the accelerator only
+ with the Win95/98 look. Same goes for the menu entry text.
+ * win/tkWinX.c (TkWinGetPlatformId, TkWinGetPlatformTheme):
+ Automatically detect the Windows theme in use and return
+ either TK_THEME_WIN_CLASSIC or TK_THEME_WIN_XP when the
+ TkWinGetPlatformTheme function is invoked.
+ [Patch 866194]
+
+2004-09-22 Vince Darley <vincentdarley@users.sourceforge.net>
+
+ * win/tkWinMenu.c: only provide a submenu handle when the
+ MF_POPUP flag is given, fixing a recently-introduced crash
+ when submenus are disabled. Also better error checking for
+ this sort of situation in the future.
+
+2004-09-22 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tkWinMenu.c (ReconfigureWindowsMenu): Fix drawing of a disabled
+ (TkWinHandleMenuEvent, DrawMenuEntryArrow): cascade menu arrow. Tk was
+ displaying a disabled cascade menu arrow in black instead of
+ gray. This was caused by a bug in the Win32 code for user drawn
+ menu items. The fix is to avoid telling Windows that the menu item
+ is a cascade type and then draw the gray arrow bitmap on our own.
+ [Patch 865842]
+
+2004-09-22 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tkWinMenu.c (DrawWindowsSystemBitmap): Fix a strange Win32
+ bug where the logical coordinates returned by a call to DPtoLP are
+ wrong the first time a menu is posted. This bug manifested itself
+ by drawing the bitmap in the wrong place in a menu. The fix was
+ to pass the newly created DC instead of the DC from the window.
+
+2004-09-22 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tkWinMenu.c (DrawMenuEntryAccelerator):
+ (DrawMenuEntryLabel): When drawing the label text and accelerator
+ text for a disabled menu entry be sure to draw a 3D highlight.
+ The only exception to this is when a disabled menu entry is
+ highlighted, in that case do not draw a 3D hightlight.
+
+2004-09-22 Mo DeJong <mdejong@users.sourceforge.net>
+
+ * win/tkWinMenu.c (DrawMenuEntryAccelerator, DrawMenuEntryArrow):
+ Move the unused menu arrow drawing code in
+ DrawMenuEntryAccelerator into a new function named
+ DrawMenuEntryArrow. This makes no functional change but it will
+ make it easier to fix things in the future.
+
+2004-09-22 Mo DeJong <mdejong@users.sourceforge.net>
+
* win/tkWinWm.c: Rework WS_EX_LAYERED and LWA_ALPHA
defines so that compiling with mingw works again.
diff --git a/generic/tkInt.decls b/generic/tkInt.decls
index eb1d607..e7fe2c7 100644
--- a/generic/tkInt.decls
+++ b/generic/tkInt.decls
@@ -9,7 +9,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: tkInt.decls,v 1.33.2.1 2003/10/13 03:30:04 hobbs Exp $
+# RCS: @(#) $Id: tkInt.decls,v 1.33.2.2 2004/09/23 00:56:14 mdejong Exp $
library tk
@@ -1130,6 +1130,10 @@ declare 66 mac {
int TkpIsWindowFloating (WindowRef window)
}
+declare 35 win {
+ int TkWinGetPlatformTheme (void)
+}
+
########################
# Mac OS X specific functions
diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h
index 6719448..f8633a9 100644
--- a/generic/tkIntPlatDecls.h
+++ b/generic/tkIntPlatDecls.h
@@ -9,7 +9,7 @@
* Copyright (c) 1998-1999 by Scriptics Corporation.
* All rights reserved.
*
- * RCS: @(#) $Id: tkIntPlatDecls.h,v 1.15 2002/12/08 00:46:51 hobbs Exp $
+ * RCS: @(#) $Id: tkIntPlatDecls.h,v 1.15.2.1 2004/09/23 00:56:14 mdejong Exp $
*/
#ifndef _TKINTPLATDECLS
@@ -123,6 +123,8 @@ EXTERN Tcl_Obj * TkWinGetMenuSystemDefault _ANSI_ARGS_((
EXTERN int TkWinGetPlatformId _ANSI_ARGS_((void));
/* 34 */
EXTERN void TkWinSetHINSTANCE _ANSI_ARGS_((HINSTANCE hInstance));
+/* 35 */
+EXTERN int TkWinGetPlatformTheme _ANSI_ARGS_((void));
#endif /* __WIN32__ */
#ifdef MAC_TCL
/* 0 */
@@ -462,6 +464,7 @@ typedef struct TkIntPlatStubs {
Tcl_Obj * (*tkWinGetMenuSystemDefault) _ANSI_ARGS_((Tk_Window tkwin, CONST char * dbName, CONST char * className)); /* 32 */
int (*tkWinGetPlatformId) _ANSI_ARGS_((void)); /* 33 */
void (*tkWinSetHINSTANCE) _ANSI_ARGS_((HINSTANCE hInstance)); /* 34 */
+ int (*tkWinGetPlatformTheme) _ANSI_ARGS_((void)); /* 35 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
void (*tkGenerateActivateEvents) _ANSI_ARGS_((TkWindow * winPtr, int active)); /* 0 */
@@ -757,6 +760,10 @@ extern TkIntPlatStubs *tkIntPlatStubsPtr;
#define TkWinSetHINSTANCE \
(tkIntPlatStubsPtr->tkWinSetHINSTANCE) /* 34 */
#endif
+#ifndef TkWinGetPlatformTheme
+#define TkWinGetPlatformTheme \
+ (tkIntPlatStubsPtr->tkWinGetPlatformTheme) /* 35 */
+#endif
#endif /* __WIN32__ */
#ifdef MAC_TCL
#ifndef TkGenerateActivateEvents
diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c
index 335dee7..c69c88f 100644
--- a/generic/tkStubInit.c
+++ b/generic/tkStubInit.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkStubInit.c,v 1.41.2.1 2003/10/13 03:30:05 hobbs Exp $
+ * RCS: @(#) $Id: tkStubInit.c,v 1.41.2.2 2004/09/23 00:56:14 mdejong Exp $
*/
#include "tkInt.h"
@@ -371,6 +371,7 @@ TkIntPlatStubs tkIntPlatStubs = {
TkWinGetMenuSystemDefault, /* 32 */
TkWinGetPlatformId, /* 33 */
TkWinSetHINSTANCE, /* 34 */
+ TkWinGetPlatformTheme, /* 35 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
TkGenerateActivateEvents, /* 0 */
diff --git a/win/tkWinInt.h b/win/tkWinInt.h
index 0266099..7a1d1d7 100644
--- a/win/tkWinInt.h
+++ b/win/tkWinInt.h
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinInt.h,v 1.14.2.3 2004/09/17 23:36:16 hobbs Exp $
+ * RCS: @(#) $Id: tkWinInt.h,v 1.14.2.4 2004/09/23 00:56:15 mdejong Exp $
*/
#ifndef _TKWININT
@@ -210,5 +210,11 @@ EXTERN TkWinProcs *tkWinProcs;
extern Tcl_Encoding TkWinGetKeyInputEncoding _ANSI_ARGS_((void));
extern Tcl_Encoding TkWinGetUnicodeEncoding _ANSI_ARGS_((void));
+/*
+ * Values returned by TkWinGetPlatformTheme.
+ */
+#define TK_THEME_WIN_CLASSIC 1
+#define TK_THEME_WIN_XP 2
+
#endif /* _TKWININT */
diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c
index aea7d73..8dec5d8 100644
--- a/win/tkWinMenu.c
+++ b/win/tkWinMenu.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinMenu.c,v 1.21.2.2 2004/05/03 23:23:42 hobbs Exp $
+ * RCS: @(#) $Id: tkWinMenu.c,v 1.21.2.3 2004/09/23 00:56:15 mdejong Exp $
*/
#define OEMRESOURCE
@@ -91,6 +91,11 @@ static void DrawMenuEntryAccelerator _ANSI_ARGS_((
Drawable d, GC gc, Tk_Font tkfont,
CONST Tk_FontMetrics *fmPtr,
Tk_3DBorder activeBorder, int x, int y,
+ int width, int height));
+static void DrawMenuEntryArrow _ANSI_ARGS_((
+ TkMenu *menuPtr, TkMenuEntry *mePtr,
+ Drawable d, GC gc,
+ Tk_3DBorder activeBorder, int x, int y,
int width, int height, int drawArrow));
static void DrawMenuEntryBackground _ANSI_ARGS_((
TkMenu *menuPtr, TkMenuEntry *mePtr,
@@ -124,7 +129,7 @@ static void DrawWindowsSystemBitmap _ANSI_ARGS_((
Display *display, Drawable drawable,
GC gc, CONST RECT *rectPtr, int bitmapID,
int alignFlags));
-static void FreeID _ANSI_ARGS_((int commandID));
+static void FreeID _ANSI_ARGS_((WORD commandID));
static TCHAR * GetEntryText _ANSI_ARGS_((TkMenuEntry *mePtr));
static void GetMenuAccelGeometry _ANSI_ARGS_((TkMenu *menuPtr,
TkMenuEntry *mePtr, Tk_Font tkfont,
@@ -146,7 +151,7 @@ static void GetTearoffEntryGeometry _ANSI_ARGS_((TkMenu *menuPtr,
CONST Tk_FontMetrics *fmPtr, int *widthPtr,
int *heightPtr));
static int GetNewID _ANSI_ARGS_((TkMenuEntry *mePtr,
- int *menuIDPtr));
+ WORD *menuIDPtr));
static int MenuKeyBindProc _ANSI_ARGS_((
ClientData clientData,
Tcl_Interp *interp, XEvent *eventPtr,
@@ -186,7 +191,7 @@ static LRESULT CALLBACK TkWinMenuProc _ANSI_ARGS_((HWND hwnd,
static int
GetNewID(mePtr, menuIDPtr)
TkMenuEntry *mePtr; /* The menu we are working with */
- int *menuIDPtr; /* The resulting id */
+ WORD *menuIDPtr; /* The resulting id */
{
int found = 0;
int newEntry;
@@ -215,7 +220,7 @@ GetNewID(mePtr, menuIDPtr)
if (found) {
Tcl_SetHashValue(commandEntryPtr, (char *) mePtr);
- *menuIDPtr = (int) returnID;
+ *menuIDPtr = returnID;
tsdPtr->lastCommandID = returnID;
return TCL_OK;
} else {
@@ -241,7 +246,7 @@ GetNewID(mePtr, menuIDPtr)
static void
FreeID(commandID)
- int commandID;
+ WORD commandID;
{
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@@ -414,7 +419,7 @@ TkpDestroyMenuEntry(mePtr)
Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);
}
}
- FreeID((int) mePtr->platformEntryData);
+ FreeID((WORD) mePtr->platformEntryData);
mePtr->platformEntryData = NULL;
}
@@ -572,6 +577,7 @@ ReconfigureWindowsMenu(
|| (menuPtr->menuFlags & MENU_SYSTEM_MENU)) {
Tcl_WinUtfToTChar(itemText, -1, &translatedText);
lpNewItem = Tcl_DStringValue(&translatedText);
+ flags |= MF_STRING;
} else {
lpNewItem = (LPCTSTR) mePtr;
flags |= MF_OWNERDRAW;
@@ -611,15 +617,27 @@ ReconfigureWindowsMenu(
flags |= MF_MENUBREAK;
}
- itemID = (int) mePtr->platformEntryData;
+ itemID = (UINT) mePtr->platformEntryData;
if ((mePtr->type == CASCADE_ENTRY)
&& (mePtr->childMenuRefPtr != NULL)
&& (mePtr->childMenuRefPtr->menuPtr != NULL)) {
HMENU childMenuHdl = (HMENU) mePtr->childMenuRefPtr->menuPtr
->platformData;
if (childMenuHdl != NULL) {
- itemID = (UINT) childMenuHdl;
- flags |= MF_POPUP;
+ /*
+ * Win32 draws the popup arrow in the wrong color
+ * for a disabled cascade menu, so do it by hand.
+ * Given it is disabled, there's no need for it to
+ * be connected to its child.
+ */
+ if (mePtr->state != ENTRY_DISABLED) {
+ flags |= MF_POPUP;
+ /*
+ * If the MF_POPUP flag is set, then the id
+ * is interpreted as the handle of a submenu.
+ */
+ itemID = (UINT) childMenuHdl;
+ }
}
if ((menuPtr->menuType == MENUBAR)
&& !(mePtr->childMenuRefPtr->menuPtr->menuFlags
@@ -815,7 +833,7 @@ int
TkpMenuNewEntry(mePtr)
TkMenuEntry *mePtr;
{
- int commandID;
+ WORD commandID;
TkMenu *menuPtr = mePtr->menuPtr;
if (GetNewID(mePtr, &commandID) != TCL_OK) {
@@ -1064,6 +1082,7 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult)
TkWinDrawable *twdPtr;
LPDRAWITEMSTRUCT itemPtr = (LPDRAWITEMSTRUCT) *plParam;
Tk_FontMetrics fontMetrics;
+ int drawArrow = 0;
if (itemPtr != NULL) {
Tk_Font tkfont;
@@ -1092,6 +1111,12 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult)
} else {
mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1;
}
+ /* Also, set the drawArrow flag for a disabled cascade
+ ** menu since we need to draw the arrow ourselves.
+ */
+ if (mePtr->type == CASCADE_ENTRY) {
+ drawArrow = 1;
+ }
}
tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr);
@@ -1100,7 +1125,7 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult)
&fontMetrics, itemPtr->rcItem.left,
itemPtr->rcItem.top, itemPtr->rcItem.right
- itemPtr->rcItem.left, itemPtr->rcItem.bottom
- - itemPtr->rcItem.top, 0, 0);
+ - itemPtr->rcItem.top, 0, drawArrow);
ckfree((char *) twdPtr);
*plResult = 1;
@@ -1148,6 +1173,9 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult)
if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) {
TkActivateMenuEntry(menuPtr, -1);
} else {
+ if (mePtr->index >= menuPtr->numEntries) {
+ Tcl_Panic("Trying to activate an entry which doesn't exist.");
+ }
TkActivateMenuEntry(menuPtr, mePtr->index);
}
MenuSelectEvent(menuPtr);
@@ -1464,7 +1492,7 @@ DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags)
GetObject(bitmap, sizeof(BITMAP), &bm);
ptSize.x = bm.bmWidth;
ptSize.y = bm.bmHeight;
- DPtoLP(hdc, &ptSize, 1);
+ DPtoLP(scratchDC, &ptSize, 1);
ptOrg.y = ptOrg.x = 0;
DPtoLP(scratchDC, &ptOrg, 1);
@@ -1571,15 +1599,17 @@ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x,
*
* DrawMenuEntryAccelerator --
*
- * This procedure draws the accelerator part of a menu. We
- * need to decide what to draw here. Should we replace strings
+ * This procedure draws the accelerator part of a menu.
+ * For example, the string "CTRL-Z" could be drawn to
+ * to the right of the label text for an Undo menu entry.
+ * Need to decide what to draw here. Should we replace strings
* like "Control", "Command", etc?
*
* Results:
* None.
*
* Side effects:
- * Commands are output to X to display the menu in its
+ * Commands are output to display the menu in its
* current mode.
*
*----------------------------------------------------------------------
@@ -1587,7 +1617,7 @@ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x,
void
DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
- activeBorder, x, y, width, height, drawArrow)
+ activeBorder, x, y, width, height)
TkMenu *menuPtr; /* The menu we are drawing */
TkMenuEntry *mePtr; /* The entry we are drawing */
Drawable d; /* What we are drawing into */
@@ -1599,10 +1629,6 @@ DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
int y; /* top edge */
int width; /* Width of menu entry */
int height; /* Height of menu entry */
- int drawArrow; /* For cascade menus, whether of not
- * to draw the arraw. I cannot figure
- * out Windows' algorithm for where
- * to draw this. */
{
int baseline;
int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth;
@@ -1614,45 +1640,97 @@ DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
- if ((mePtr->state == ENTRY_DISABLED) && (menuPtr->disabledFgPtr != NULL)
- && ((mePtr->accelPtr != NULL)
- || ((mePtr->type == CASCADE_ENTRY) && drawArrow))) {
- COLORREF oldFgColor = gc->foreground;
+ /* Draw disabled 3D text highlight only with the Win95/98 look. */
- gc->foreground = GetSysColor(COLOR_3DHILIGHT);
- if (mePtr->accelPtr != NULL) {
- Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
- mePtr->accelLength, leftEdge + 1, baseline + 1);
- }
+ if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) {
+ if ((mePtr->state == ENTRY_DISABLED) && (menuPtr->disabledFgPtr != NULL)
+ && (mePtr->accelPtr != NULL)) {
+ COLORREF oldFgColor = gc->foreground;
- if (mePtr->type == CASCADE_ENTRY) {
- RECT rect;
-
- rect.top = y + GetSystemMetrics(SM_CYBORDER) + 1;
- rect.bottom = y + height - GetSystemMetrics(SM_CYBORDER) + 1;
- rect.left = x + mePtr->indicatorSpace + mePtr->labelWidth + 1;
- rect.right = x + width;
- DrawWindowsSystemBitmap(menuPtr->display, d, gc, &rect,
- OBM_MNARROW, ALIGN_BITMAP_RIGHT);
+ gc->foreground = GetSysColor(COLOR_3DHILIGHT);
+ if ((mePtr->accelPtr != NULL) &&
+ ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0)) {
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
+ mePtr->accelLength, leftEdge + 1, baseline + 1);
+ }
+ gc->foreground = oldFgColor;
}
- gc->foreground = oldFgColor;
}
if (mePtr->accelPtr != NULL) {
Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel,
mePtr->accelLength, leftEdge, baseline);
}
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DrawMenuEntryArrow --
+ *
+ * This function draws the arrow bitmap on the right side of a
+ * a menu entry. This function is currently unused.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
- if ((mePtr->type == CASCADE_ENTRY) && drawArrow) {
- RECT rect;
+void
+DrawMenuEntryArrow(menuPtr, mePtr, d, gc,
+ activeBorder, x, y, width, height, drawArrow)
+ TkMenu *menuPtr; /* The menu we are drawing */
+ TkMenuEntry *mePtr; /* The entry we are drawing */
+ Drawable d; /* What we are drawing into */
+ GC gc; /* The gc we are drawing with */
+ Tk_3DBorder activeBorder; /* The border when an item is active */
+ int x; /* left edge */
+ int y; /* top edge */
+ int width; /* Width of menu entry */
+ int height; /* Height of menu entry */
+ int drawArrow; /* For cascade menus, whether of not
+ * to draw the arraw. I cannot figure
+ * out Windows' algorithm for where
+ * to draw this. */
+{
+ COLORREF oldFgColor;
+ COLORREF oldBgColor;
+ RECT rect;
+
+ if (!drawArrow || (mePtr->type != CASCADE_ENTRY) ||
+ (mePtr->state != ENTRY_DISABLED))
+ return;
+
+ oldFgColor = gc->foreground;
+ oldBgColor = gc->background;
- rect.top = y + GetSystemMetrics(SM_CYBORDER);
- rect.bottom = y + height - GetSystemMetrics(SM_CYBORDER);
- rect.left = x + mePtr->indicatorSpace + mePtr->labelWidth;
- rect.right = x + width - 1;
- DrawWindowsSystemBitmap(menuPtr->display, d, gc, &rect, OBM_MNARROW,
- ALIGN_BITMAP_RIGHT);
+ /* Set bitmap bg to highlight color if the menu is highlighted */
+ if (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) {
+ XColor *activeBgColor = Tk_3DBorderColor(Tk_Get3DBorderFromObj(
+ mePtr->menuPtr->tkwin,
+ (mePtr->activeBorderPtr == NULL) ?
+ mePtr->menuPtr->activeBorderPtr :
+ mePtr->activeBorderPtr));
+ gc->background = activeBgColor->pixel;
}
+
+ gc->foreground = GetSysColor(COLOR_GRAYTEXT);
+
+ rect.top = y + GetSystemMetrics(SM_CYBORDER);
+ rect.bottom = y + height - GetSystemMetrics(SM_CYBORDER);
+ rect.left = x + mePtr->indicatorSpace + mePtr->labelWidth;
+ rect.right = x + width;
+
+ DrawWindowsSystemBitmap(menuPtr->display, d, gc, &rect, OBM_MNARROW,
+ ALIGN_BITMAP_RIGHT);
+
+ gc->foreground = oldFgColor;
+ gc->background = oldBgColor;
+ return;
}
/*
@@ -2045,13 +2123,26 @@ DrawMenuEntryLabel(
if (mePtr->labelLength > 0) {
int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2;
char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL);
+ if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) {
+ /* Win 95/98 systems draw disabled menu text with a
+ * 3D highlight, unless the menu item is highlighted */
+ if ((mePtr->state == ENTRY_DISABLED) &&
+ ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0)) {
+ COLORREF oldFgColor = gc->foreground;
+ gc->foreground = GetSysColor(COLOR_3DHILIGHT);
+ Tk_DrawChars(menuPtr->display, d, gc, tkfont, label,
+ mePtr->labelLength, leftEdge + textXOffset + 1,
+ baseline + textYOffset + 1);
+ gc->foreground = oldFgColor;
+ }
+ }
Tk_DrawChars(menuPtr->display, d, gc, tkfont, label,
mePtr->labelLength, leftEdge + textXOffset,
baseline + textYOffset);
DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr,
x + textXOffset, y + textYOffset,
width, height);
- }
+ }
}
if (mePtr->state == ENTRY_DISABLED) {
@@ -2308,6 +2399,8 @@ TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height,
DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
width, adjustedHeight);
DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
+ activeBorder, x, adjustedY, width, adjustedHeight);
+ DrawMenuEntryArrow(menuPtr, mePtr, d, gc,
activeBorder, x, adjustedY, width, adjustedHeight, drawArrow);
if (!mePtr->hideMargin) {
DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont,
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 550bc34..94b3c6c 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinX.c,v 1.25.2.2 2004/05/03 22:40:58 hobbs Exp $
+ * RCS: @(#) $Id: tkWinX.c,v 1.25.2.3 2004/09/23 00:56:15 mdejong Exp $
*/
#include "tkWinInt.h"
@@ -84,6 +84,7 @@ static HINSTANCE tkInstance = NULL; /* Application instance handle. */
static int childClassInitialized; /* Registered child class? */
static WNDCLASS childClass; /* Window class for child windows. */
static int tkPlatformId = 0; /* version of Windows platform */
+static int tkWinTheme = 0; /* See TkWinGetPlatformTheme */
static Tcl_Encoding keyInputEncoding = NULL;/* The current character
* encoding for keyboard input */
static int keyInputCharset = -1; /* The Win32 CHARSET for the keyboard
@@ -356,6 +357,33 @@ TkWinGetPlatformId()
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&os);
tkPlatformId = os.dwPlatformId;
+
+ /* Set tkWinTheme to be TK_THEME_WIN_XP or TK_THEME_WIN_CLASSIC.
+ * The TK_THEME_WIN_CLASSIC could be set even when running
+ * under XP if the windows classic theme was selected. */
+ if ((os.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
+ (os.dwMajorVersion == 5 && os.dwMinorVersion == 1)) {
+ HKEY hKey;
+ LPCSTR szSubKey = TEXT("Control Panel\\Appearance");
+ LPCSTR szCurrent = TEXT("Current");
+ DWORD dwSize = 200;
+ char pBuffer[200];
+ memset(pBuffer, 0, dwSize);
+ if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0L,
+ KEY_READ, &hKey) != ERROR_SUCCESS) {
+ tkWinTheme = TK_THEME_WIN_XP;
+ } else {
+ RegQueryValueEx(hKey, szCurrent, NULL, NULL, pBuffer, &dwSize);
+ RegCloseKey(hKey);
+ if (strcmp(pBuffer, "Windows Standard") == 0) {
+ tkWinTheme = TK_THEME_WIN_CLASSIC;
+ } else {
+ tkWinTheme = TK_THEME_WIN_XP;
+ }
+ }
+ } else {
+ tkWinTheme = TK_THEME_WIN_CLASSIC;
+ }
}
return tkPlatformId;
}
@@ -363,6 +391,33 @@ TkWinGetPlatformId()
/*
*----------------------------------------------------------------------
*
+ * TkWinGetPlatformTheme --
+ *
+ * Return the Windows drawing style we should be using.
+ *
+ * Results:
+ * The return value is one of:
+ * TK_THEME_WIN_CLASSIC 95/98/NT or XP in classic mode
+ * TK_THEME_WIN_XP XP not in classic mode
+ *
+ * Side effects:
+ * Could invoke TkWinGetPlatformId.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkWinGetPlatformTheme()
+{
+ if (tkPlatformId == 0) {
+ TkWinGetPlatformId();
+ }
+ return tkWinTheme;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkGetDefaultScreenName --
*
* Returns the name of the screen that Tk should use during