comctl32: [try 3] correct handling of toolbar separators' size
Igor Tarasov
tarasov.igor at gmail.com
Mon Mar 30 11:08:18 CDT 2009
Third try, resending patches again as Alexandre asked.
> Second try, applied advice from wine-devel.
> 2009/3/18 Igor Tarasov <tarasov.igor at gmail.com>:
>> Currently, wine uses iBitmap property for determining toolbar
>> separators width all the time, stating it's an undocumented feature.
>> This is not correct.
>>
>> According to MSDN, iBitmap is used only on inserting separator (since
>> there is no cx field in TBBUTTON structure).
>> http://msdn.microsoft.com/en-us/library/bb760476(VS.85).aspx
>>
>> In other cases, cx property that can be updated via get/set buttoninfo
>> is used, as tests show. Also, tests show that this property differs
>> from zero only if application specifically sets. Setting it to 0 makes
>> separator display in default width. All this is implemented in this
>> patch. More tests results in bugtracker (link below).
>>
>> As of setting iBitmap for separators: native comctl32 starts behaving
>> very buggy, misplacing button bitmaps, even outside of the buttons,
>> thus producing visual glitches. While autosizing toolbar puts bitmaps
>> at their places, but, IMHO, it's rather bug than feature.
>>
>> This patch fixes bug 17654
>> http://bugs.winehq.org/show_bug.cgi?id=17654
P.S: Best used with my previous patch ;)
http://www.winehq.org/pipermail/wine-patches/2009-March/071329.html
--
Igor
-------------- next part --------------
diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c
index 92a1366..fe4c539 100644
--- a/dlls/comctl32/toolbar.c
+++ b/dlls/comctl32/toolbar.c
@@ -1326,17 +1326,14 @@ TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle )
if (btnPtr[i].fsState & TBSTATE_HIDDEN)
continue;
- /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
- /* it is the actual width of the separator. This is used for */
- /* custom controls in toolbars. */
- /* */
+ if (btnPtr[i].cx > 0)
+ cx = btnPtr[i].cx;
/* horizontal separators are treated as buttons for width */
- if ((btnPtr[i].fsStyle & BTNS_SEP) &&
+ else if ((btnPtr[i].fsStyle & BTNS_SEP) &&
!(infoPtr->dwStyle & CCS_VERT))
- cx = (btnPtr[i].iBitmap > 0) ?
- btnPtr[i].iBitmap : SEPARATOR_WIDTH;
+ cx = SEPARATOR_WIDTH;
else
- cx = (btnPtr[i].cx) ? btnPtr[i].cx : infoPtr->nButtonWidth;
+ cx = infoPtr->nButtonWidth;
/* Two or more adjacent separators form a separator group. */
/* The first separator in a group should be wrapped to the */
@@ -1684,18 +1681,13 @@ TOOLBAR_LayoutToolbar(HWND hwnd)
cy = infoPtr->nButtonHeight;
- /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
- /* it is the actual width of the separator. This is used for */
- /* custom controls in toolbars. */
if (btnPtr->fsStyle & BTNS_SEP) {
if (infoPtr->dwStyle & CCS_VERT) {
- cy = (btnPtr->iBitmap > 0) ?
- btnPtr->iBitmap : SEPARATOR_WIDTH;
- cx = infoPtr->nButtonWidth;
+ cy = SEPARATOR_WIDTH;
+ cx = (btnPtr->cx > 0) ? btnPtr->cx : infoPtr->nButtonWidth;
}
else
- cx = (btnPtr->iBitmap > 0) ?
- btnPtr->iBitmap : SEPARATOR_WIDTH;
+ cx = (btnPtr->cx > 0) ? btnPtr->cx : SEPARATOR_WIDTH;
}
else
{
@@ -1758,12 +1750,9 @@ TOOLBAR_LayoutToolbar(HWND hwnd)
y += cy;
else
{
- /* UNDOCUMENTED: If a separator has a non zero bitmap index, */
- /* it is the actual width of the separator. This is used for */
- /* custom controls in toolbars. */
if ( !(infoPtr->dwStyle & CCS_VERT))
- y += cy + ( (btnPtr->iBitmap > 0 ) ?
- btnPtr->iBitmap : SEPARATOR_WIDTH) * 2 /3;
+ y += cy + ( (btnPtr->cx > 0 ) ?
+ btnPtr->cx : SEPARATOR_WIDTH) * 2 /3;
else
y += cy;
@@ -1845,7 +1834,12 @@ TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButto
TOOLBAR_DumpTBButton(lpTbb, fUnicode);
ZeroMemory(btnPtr, sizeof(*btnPtr));
- btnPtr->iBitmap = lpTbb[iButton].iBitmap;
+
+ /* When inserting separator, iBitmap controls it's size */
+ if (lpTbb[iButton].fsStyle & BTNS_SEP) {
+ btnPtr->cx = lpTbb[iButton].iBitmap;
+ } else
+ btnPtr->iBitmap = lpTbb[iButton].iBitmap;
btnPtr->idCommand = lpTbb[iButton].idCommand;
btnPtr->fsState = lpTbb[iButton].fsState;
btnPtr->fsStyle = lpTbb[iButton].fsStyle;
@@ -3400,7 +3394,11 @@ TOOLBAR_GetButtonInfoT(HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
if (lpTbInfo->dwMask & TBIF_LPARAM)
lpTbInfo->lParam = btnPtr->dwData;
if (lpTbInfo->dwMask & TBIF_SIZE)
- lpTbInfo->cx = (WORD)(btnPtr->rect.right - btnPtr->rect.left);
+ /* tests show that for separators TBIF_SIZE returns not calculated width,
+ but cx property, that differs from 0 only if application have
+ specifically set it */
+ lpTbInfo->cx = (btnPtr->fsStyle & BTNS_SEP)
+ ? btnPtr->cx : (WORD)(btnPtr->rect.right - btnPtr->rect.left);
if (lpTbInfo->dwMask & TBIF_STATE)
lpTbInfo->fsState = btnPtr->fsState;
if (lpTbInfo->dwMask & TBIF_STYLE)
@@ -4240,7 +4238,9 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
{
/* separator */
nmtbr.tbButton.fsStyle = TBSTYLE_SEP;
- nmtbr.tbButton.iBitmap = SEPARATOR_WIDTH;
+ /* when inserting separators, iBitmap controls it's size.
+ 0 sets default size (width) */
+ nmtbr.tbButton.iBitmap = 0;
}
else if (*nmtbr.pCurrent == (DWORD)-2)
/* hidden button */
More information about the wine-patches
mailing list