summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--win/tkWinMenu.c85
2 files changed, 61 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 17a0a18..594ff88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-02-23 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+ * win/tkWinMenu.c: Applied patch for menu image display bug
+ [Bug 1329198, 456299] [Patch 2507419] (cjmcdonald)
+
2009-02-17 Jeff Hobbs <jeffh@ActiveState.com>
* win/tcl.m4, win/configure: Check if cl groks _WIN64 already to
diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c
index 2e077b8..004cd14 100644
--- a/win/tkWinMenu.c
+++ b/win/tkWinMenu.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: tkWinMenu.c,v 1.59 2007/12/13 15:28:56 dgp Exp $
+ * RCS: @(#) $Id: tkWinMenu.c,v 1.59.2.1 2009/02/23 10:37:38 patthoyts Exp $
*/
#define OEMRESOURCE
@@ -35,9 +35,6 @@
#define ALIGN_BITMAP_TOP 0x00000004
#define ALIGN_BITMAP_BOTTOM 0x00000008
-#ifndef TPM_NOANIMATION
-#define TPM_NOANIMATION 0x4000L
-#endif
/*
* Platform-specific menu flags:
@@ -715,12 +712,11 @@ TkpPostMenu(
int x, int y)
{
HMENU winMenuHdl = (HMENU) menuPtr->platformData;
- int i, result, flags;
+ int result, flags;
RECT noGoawayRect;
POINT point;
Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin);
int oldServiceMode = Tcl_GetServiceMode();
- TkMenuEntry *mePtr;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@@ -783,18 +779,6 @@ TkpPostMenu(
}
}
- /*
- * Disable menu animation if an image is present, as clipping isn't
- * handled correctly with temp DCs. [Bug 1329198]
- */
- for (i = 0; i < menuPtr->numEntries; i++) {
- mePtr = menuPtr->entries[i];
- if (mePtr->image != NULL) {
- flags |= TPM_NOANIMATION;
- break;
- }
- }
-
TrackPopupMenu(winMenuHdl, flags, x, y, 0,
tsdPtr->menuHWND, &noGoawayRect);
Tcl_SetServiceMode(oldServiceMode);
@@ -2429,7 +2413,7 @@ TkpConfigureMenuEntry(
void
TkpDrawMenuEntry(
TkMenuEntry *mePtr, /* The entry to draw */
- Drawable d, /* What to draw into */
+ Drawable menuDrawable, /* Menu to draw into */
Tk_Font tkfont, /* Precalculated font for menu */
const Tk_FontMetrics *menuMetricsPtr,
/* Precalculated metrics for menu */
@@ -2448,8 +2432,38 @@ TkpDrawMenuEntry(
const Tk_FontMetrics *fmPtr;
Tk_FontMetrics entryMetrics;
int padY = (menuPtr->menuType == MENUBAR) ? 3 : 0;
- int adjustedY = y + padY;
+ int adjustedX, adjustedY;
int adjustedHeight = height - 2 * padY;
+ TkWinDrawable memWinDraw;
+ TkWinDCState dcState;
+ HBITMAP oldBitmap;
+ Drawable d;
+ HDC memDc, menuDc;
+
+ /*
+ * If the menu entry includes an image then draw the entry into a
+ * compatible bitmap first. This avoids problems with clipping on
+ * animated menus. [Bug 1329198]
+ */
+
+ if (mePtr->image != NULL) {
+ menuDc = TkWinGetDrawableDC(menuPtr->display, menuDrawable, &dcState);
+
+ memDc = CreateCompatibleDC(menuDc);
+ oldBitmap = SelectObject(memDc,
+ CreateCompatibleBitmap(menuDc, width, height) );
+
+ memWinDraw.type = TWD_WINDC;
+ memWinDraw.winDC.hdc = memDc;
+ d = (Drawable)&memWinDraw;
+ adjustedX = 0;
+ adjustedY = padY;
+
+ } else {
+ d = menuDrawable;
+ adjustedX = x;
+ adjustedY = y + padY;
+ }
/*
* Choose the gc for drawing the foreground part of the entry.
@@ -2521,26 +2535,39 @@ TkpDrawMenuEntry(
*/
DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder,
- bgBorder, x, y, width, height);
+ bgBorder, adjustedX, adjustedY-padY, width, height);
if (mePtr->type == SEPARATOR_ENTRY) {
DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont,
- fmPtr, x, adjustedY, width, adjustedHeight);
+ fmPtr, adjustedX, adjustedY, width, adjustedHeight);
} else if (mePtr->type == TEAROFF_ENTRY) {
- DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
- width, adjustedHeight);
+ DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr,
+ adjustedX, adjustedY, width, adjustedHeight);
} else {
- DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
- width, adjustedHeight);
+ DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr,
+ adjustedX, adjustedY, width, adjustedHeight);
DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
- activeBorder, x, adjustedY, width, adjustedHeight);
+ activeBorder, adjustedX, adjustedY, width, adjustedHeight);
DrawMenuEntryArrow(menuPtr, mePtr, d, gc,
- activeBorder, x, adjustedY, width, adjustedHeight, drawArrow);
+ activeBorder, adjustedX, adjustedY, width, adjustedHeight,
+ drawArrow);
if (!mePtr->hideMargin) {
DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont,
- fmPtr, x, adjustedY, width, adjustedHeight);
+ fmPtr, adjustedX, adjustedY, width, adjustedHeight);
}
}
+
+ /*
+ * Copy the entry contents from the temporary bitmap to the menu.
+ */
+
+ if (mePtr->image != NULL) {
+ BitBlt(menuDc, x, y, width, height, memDc, 0, 0, SRCCOPY);
+ DeleteObject(SelectObject(memDc, oldBitmap));
+ DeleteDC(memDc);
+
+ TkWinReleaseDrawableDC(menuDrawable, menuDc, &dcState);
+ }
}
/*