diff --git a/reactos/lib/comctl32/comctl32.h b/reactos/lib/comctl32/comctl32.h index 6b5a84d6f7a..a73911f8a91 100644 --- a/reactos/lib/comctl32/comctl32.h +++ b/reactos/lib/comctl32/comctl32.h @@ -191,4 +191,62 @@ BOOL WINAPI DPA_Merge (const HDPA, const HDPA, DWORD, PFNDPACOMPARE, PFNDPAMERGE LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet); BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2); +extern void ANIMATE_Register(void); +extern void ANIMATE_Unregister(void); +extern void COMBOEX_Register(void); +extern void COMBOEX_Unregister(void); +extern void DATETIME_Register(void); +extern void DATETIME_Unregister(void); +extern void FLATSB_Register(void); +extern void FLATSB_Unregister(void); +extern void HEADER_Register(void); +extern void HEADER_Unregister(void); +extern void HOTKEY_Register(void); +extern void HOTKEY_Unregister(void); +extern void IPADDRESS_Register(void); +extern void IPADDRESS_Unregister(void); +extern void LISTVIEW_Register(void); +extern void LISTVIEW_Unregister(void); +extern void MONTHCAL_Register(void); +extern void MONTHCAL_Unregister(void); +extern void NATIVEFONT_Register(void); +extern void NATIVEFONT_Unregister(void); +extern void PAGER_Register(void); +extern void PAGER_Unregister(void); +extern void PROGRESS_Register(void); +extern void PROGRESS_Unregister(void); +extern void REBAR_Register(void); +extern void REBAR_Unregister(void); +extern void STATUS_Register(void); +extern void STATUS_Unregister(void); +extern void SYSLINK_Register(void); +extern void SYSLINK_Unregister(void); +extern void TAB_Register(void); +extern void TAB_Unregister(void); +extern void TOOLBAR_Register(void); +extern void TOOLBAR_Unregister(void); +extern void TOOLTIPS_Register(void); +extern void TOOLTIPS_Unregister(void); +extern void TRACKBAR_Register(void); +extern void TRACKBAR_Unregister(void); +extern void TREEVIEW_Register(void); +extern void TREEVIEW_Unregister(void); +extern void UPDOWN_Register(void); +extern void UPDOWN_Unregister(void); + + +int MONTHCAL_MonthLength(int month, int year); + +static inline void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to) +{ + to->wYear = from->wYear; + to->wMonth = from->wMonth; + to->wDayOfWeek = from->wDayOfWeek; + to->wDay = from->wDay; + to->wHour = from->wHour; + to->wMinute = from->wMinute; + to->wSecond = from->wSecond; + to->wMilliseconds = from->wMilliseconds; +} + #endif /* __WINE_COMCTL32_H */ diff --git a/reactos/lib/comctl32/commctrl.c b/reactos/lib/comctl32/commctrl.c index c10adeddd3c..0d315e97173 100644 --- a/reactos/lib/comctl32/commctrl.c +++ b/reactos/lib/comctl32/commctrl.c @@ -73,49 +73,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(commctrl); -extern void ANIMATE_Register(void); -extern void ANIMATE_Unregister(void); -extern void COMBOEX_Register(void); -extern void COMBOEX_Unregister(void); -extern void DATETIME_Register(void); -extern void DATETIME_Unregister(void); -extern void FLATSB_Register(void); -extern void FLATSB_Unregister(void); -extern void HEADER_Register(void); -extern void HEADER_Unregister(void); -extern void HOTKEY_Register(void); -extern void HOTKEY_Unregister(void); -extern void IPADDRESS_Register(void); -extern void IPADDRESS_Unregister(void); -extern void LISTVIEW_Register(void); -extern void LISTVIEW_Unregister(void); -extern void MONTHCAL_Register(void); -extern void MONTHCAL_Unregister(void); -extern void NATIVEFONT_Register(void); -extern void NATIVEFONT_Unregister(void); -extern void PAGER_Register(void); -extern void PAGER_Unregister(void); -extern void PROGRESS_Register(void); -extern void PROGRESS_Unregister(void); -extern void REBAR_Register(void); -extern void REBAR_Unregister(void); -extern void STATUS_Register(void); -extern void STATUS_Unregister(void); -extern void SYSLINK_Register(void); -extern void SYSLINK_Unregister(void); -extern void TAB_Register(void); -extern void TAB_Unregister(void); -extern void TOOLBAR_Register(void); -extern void TOOLBAR_Unregister(void); -extern void TOOLTIPS_Register(void); -extern void TOOLTIPS_Unregister(void); -extern void TRACKBAR_Register(void); -extern void TRACKBAR_Unregister(void); -extern void TREEVIEW_Register(void); -extern void TREEVIEW_Unregister(void); -extern void UPDOWN_Register(void); -extern void UPDOWN_Unregister(void); - LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LPWSTR COMCTL32_wSubclass = NULL; diff --git a/reactos/lib/comctl32/flatsb.c b/reactos/lib/comctl32/flatsb.c index baebbe68244..6d16c3c0aa8 100644 --- a/reactos/lib/comctl32/flatsb.c +++ b/reactos/lib/comctl32/flatsb.c @@ -36,6 +36,7 @@ #include "winerror.h" #include "winuser.h" #include "commctrl.h" +#include "comctl32.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(commctrl); diff --git a/reactos/lib/comctl32/ipaddress.c b/reactos/lib/comctl32/ipaddress.c index 1e0f50c7b4c..5dd0cc166fd 100644 --- a/reactos/lib/comctl32/ipaddress.c +++ b/reactos/lib/comctl32/ipaddress.c @@ -346,11 +346,7 @@ static void IPADDRESS_SetFocusToField (IPADDRESS_INFO *infoPtr, INT index) { TRACE("(index=%d)\n", index); - if (index > 3) { - for (index = 0; index < 4; index++) - if (!GetWindowTextLengthW(infoPtr->Part[index].EditHwnd)) break; - } - if (index < 9 || index > 3) index = 0; + if (index > 3 || index < 0) index=0; SetFocus (infoPtr->Part[index].EditHwnd); } diff --git a/reactos/lib/comctl32/listview.c b/reactos/lib/comctl32/listview.c index 8bd2d9f0b1e..c9f9e9d7176 100644 --- a/reactos/lib/comctl32/listview.c +++ b/reactos/lib/comctl32/listview.c @@ -277,7 +277,8 @@ typedef struct tagLISTVIEW_INFO HFONT hDefaultFont; HFONT hFont; INT ntmHeight; /* Some cached metrics of the font used */ - INT ntmAveCharWidth; /* by the listview to draw items */ + INT ntmMaxCharWidth; /* by the listview to draw items */ + INT nEllipsisWidth; BOOL bRedraw; /* Turns on/off repaints & invalidations */ BOOL bAutoarrange; /* Autoarrange flag when NOT in LVS_AUTOARRANGE */ BOOL bFocus; @@ -307,6 +308,7 @@ typedef struct tagLISTVIEW_INFO INT nSearchParamLength; WCHAR szSearchParam[ MAX_PATH ]; BOOL bIsDrawing; + INT nMeasureItemHeight; } LISTVIEW_INFO; /* @@ -548,7 +550,7 @@ static inline LPCSTR debugtext_tn(LPCWSTR text, BOOL isW, INT n) return isW ? debugstr_wn(text, n) : debugstr_an((LPCSTR)text, n); } -static char* debug_getbuf() +static char* debug_getbuf(void) { static int index = 0; static char buffers[DEBUG_BUFFERS][DEBUG_BUFFER_SIZE]; @@ -2454,6 +2456,8 @@ static INT LISTVIEW_CalculateItemHeight(LISTVIEW_INFO *infoPtr) nItemHeight = max(nItemHeight, infoPtr->iconSize.cy); if (infoPtr->himlState || infoPtr->himlSmall) nItemHeight += HEIGHT_PADDING; + if (infoPtr->nMeasureItemHeight > 0) + nItemHeight = infoPtr->nMeasureItemHeight; } return max(nItemHeight, 1); @@ -2491,12 +2495,17 @@ static void LISTVIEW_SaveTextMetrics(LISTVIEW_INFO *infoPtr) HFONT hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont; HFONT hOldFont = SelectObject(hdc, hFont); TEXTMETRICW tm; + SIZE sz; if (GetTextMetricsW(hdc, &tm)) { infoPtr->ntmHeight = tm.tmHeight; - infoPtr->ntmAveCharWidth = tm.tmAveCharWidth; + infoPtr->ntmMaxCharWidth = tm.tmMaxCharWidth; } + + if (GetTextExtentPoint32A(hdc, "...", 3, &sz)) + infoPtr->nEllipsisWidth = sz.cx; + SelectObject(hdc, hOldFont); ReleaseDC(infoPtr->hwndSelf, hdc); @@ -4268,6 +4277,7 @@ static void LISTVIEW_ScrollColumns(LISTVIEW_INFO *infoPtr, INT nColumn, INT dx) { COLUMN_INFO *lpColumnInfo; RECT rcOld, rcCol; + POINT ptOrigin; INT nCol; if (nColumn < 0 || DPA_GetPtrCount(infoPtr->hdpaColumns) < 1) return; @@ -4294,10 +4304,11 @@ static void LISTVIEW_ScrollColumns(LISTVIEW_INFO *infoPtr, INT nColumn, INT dx) infoPtr->nItemWidth += dx; LISTVIEW_UpdateScroll(infoPtr); + LISTVIEW_GetOrigin(infoPtr, &ptOrigin); /* scroll to cover the deleted column, and invalidate for redraw */ rcOld = infoPtr->rcList; - rcOld.left = rcCol.left; + rcOld.left = ptOrigin.x + rcCol.left + dx; ScrollWindowEx(infoPtr->hwndSelf, dx, 0, &rcOld, &rcOld, 0, 0, SW_ERASE | SW_INVALIDATE); /* we can restore focus now */ @@ -4562,6 +4573,17 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, LPWSTR pszText, BOOL if (!notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW)) return FALSE; if (!pszText) return TRUE; + if (!(infoPtr->dwStyle & LVS_OWNERDATA)) + { + HDPA hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, infoPtr->nEditLabelItem); + ITEM_INFO* lpItem = (ITEM_INFO *)DPA_GetPtr(hdpaSubItems, 0); + if (lpItem && lpItem->hdr.pszText == LPSTR_TEXTCALLBACKW) + { + LISTVIEW_InvalidateItem(infoPtr, infoPtr->nEditLabelItem); + return TRUE; + } + } + ZeroMemory(&dispInfo, sizeof(dispInfo)); dispInfo.item.mask = LVIF_TEXT; dispInfo.item.iItem = infoPtr->nEditLabelItem; @@ -5738,7 +5760,7 @@ static INT LISTVIEW_GetNextItem(LISTVIEW_INFO *infoPtr, INT nItem, UINT uFlags) * so it's worth optimizing */ if (uFlags & LVNI_FOCUSED) { - if (!(LISTVIEW_GetItemState(infoPtr, infoPtr->nFocusedItem, uMask) & uMask) == uMask) return -1; + if ((LISTVIEW_GetItemState(infoPtr, infoPtr->nFocusedItem, uMask) & uMask) != uMask) return -1; return (infoPtr->nFocusedItem == nItem) ? -1 : infoPtr->nFocusedItem; } @@ -6906,7 +6928,7 @@ static DWORD LISTVIEW_SetIconSpacing(LISTVIEW_INFO *infoPtr, INT cx, INT cy) return oldspacing; } -inline void set_icon_size(SIZE *size, HIMAGELIST himl, BOOL small) +static inline void set_icon_size(SIZE *size, HIMAGELIST himl, BOOL small) { INT cx, cy; @@ -7500,6 +7522,7 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs) infoPtr->iconSpacing.cy = GetSystemMetrics(SM_CYICONSPACING); infoPtr->nEditLabelItem = -1; infoPtr->dwHoverTime = -1; /* default system hover time */ + infoPtr->nMeasureItemHeight = 0; /* get default font (icon title) */ SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0); @@ -8275,21 +8298,27 @@ static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADE dx = cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left); if (dx != 0) { - RECT rcCol = lpColumnInfo->rcHeader; - lpColumnInfo->rcHeader.right += dx; LISTVIEW_ScrollColumns(infoPtr, lpnmh->iItem + 1, dx); LISTVIEW_UpdateItemSize(infoPtr); if (uView == LVS_REPORT && is_redrawing(infoPtr)) { - /* this trick works for left aligned columns only */ - if ((lpColumnInfo->fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT) - { - rcCol.right = min (rcCol.right, lpColumnInfo->rcHeader.right); - rcCol.left = max (rcCol.left, rcCol.right - 3 * infoPtr->ntmAveCharWidth); - } + POINT ptOrigin; + RECT rcCol = lpColumnInfo->rcHeader; + + LISTVIEW_GetOrigin(infoPtr, &ptOrigin); + OffsetRect(&rcCol, ptOrigin.x, 0); + rcCol.top = infoPtr->rcList.top; rcCol.bottom = infoPtr->rcList.bottom; + + /* resizing left-aligned columns leaves most of the left side untouched */ + if ((lpColumnInfo->fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT) + { + INT nMaxDirty = infoPtr->nEllipsisWidth + infoPtr->ntmMaxCharWidth + dx; + rcCol.left = max (rcCol.left, rcCol.right - nMaxDirty); + } + LISTVIEW_InvalidateRect(infoPtr, &rcCol); } } @@ -9314,8 +9343,24 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_WINDOWPOSCHANGED: if (!(((WINDOWPOS *)lParam)->flags & SWP_NOSIZE)) { + UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE); + + if ((infoPtr->dwStyle & LVS_OWNERDRAWFIXED) && (uView == LVS_REPORT)) + { + MEASUREITEMSTRUCT mis; + mis.CtlType = ODT_LISTVIEW; + mis.CtlID = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID); + mis.itemID = -1; + mis.itemWidth = 0; + mis.itemData = 0; + mis.itemHeight= infoPtr->nItemHeight; + SendMessageW(infoPtr->hwndNotify, WM_MEASUREITEM, mis.CtlID, (LPARAM)&mis); + if (infoPtr->nItemHeight != max(mis.itemHeight, 1)) + infoPtr->nMeasureItemHeight = infoPtr->nItemHeight = max(mis.itemHeight, 1); + } + LISTVIEW_UpdateSize(infoPtr); LISTVIEW_UpdateScroll(infoPtr); } @@ -9433,7 +9478,7 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP if(hFont != 0) SelectObject(hdc, hOldFont); - ReleaseDC(infoPtr->hwndSelf, hdc); + ReleaseDC(infoPtr->hwndEdit, hdc); break; } diff --git a/reactos/lib/comctl32/monthcal.c b/reactos/lib/comctl32/monthcal.c index 75fa4e47039..25047586da9 100644 --- a/reactos/lib/comctl32/monthcal.c +++ b/reactos/lib/comctl32/monthcal.c @@ -134,7 +134,7 @@ static const int DayOfWeekTable[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; /* january is 1, december is 12 */ int MONTHCAL_MonthLength(int month, int year) { -const int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}; + const int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}; /*Wrap around, this eases handling*/ if(month == 0) month = 12; @@ -170,19 +170,6 @@ static int MONTHCAL_ValidateTime(SYSTEMTIME time) } -void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to) -{ - to->wYear = from->wYear; - to->wMonth = from->wMonth; - to->wDayOfWeek = from->wDayOfWeek; - to->wDay = from->wDay; - to->wHour = from->wHour; - to->wMinute = from->wMinute; - to->wSecond = from->wSecond; - to->wMilliseconds = from->wMilliseconds; -} - - /* Note:Depending on DST, this may be offset by a day. Need to find out if we're on a DST place & adjust the clock accordingly. Above function assumes we have a valid data. @@ -212,7 +199,7 @@ static int MONTHCAL_CalcDayFromPos(MONTHCAL_INFO *infoPtr, int x, int y, GetClientRect(infoPtr->hwndSelf, &rcClient); /* if the point is outside the x bounds of the window put - it at the boundry */ + it at the boundary */ if (x > rcClient.right) x = rcClient.right; diff --git a/reactos/lib/comctl32/pager.c b/reactos/lib/comctl32/pager.c index 021489ef04d..b426a631c8d 100644 --- a/reactos/lib/comctl32/pager.c +++ b/reactos/lib/comctl32/pager.c @@ -1227,9 +1227,9 @@ PAGER_Size (PAGER_INFO* infoPtr, INT type, INT x, INT y) TRACE("[%p] %d,%d\n", infoPtr->hwndSelf, x, y); if (infoPtr->dwStyle & PGS_HORZ) - infoPtr->nHeight = x; + infoPtr->nHeight = y; else - infoPtr->nWidth = y; + infoPtr->nWidth = x; return PAGER_RecalcSize(infoPtr); } diff --git a/reactos/lib/comctl32/propsheet.c b/reactos/lib/comctl32/propsheet.c index f61463aa741..200c42982b7 100644 --- a/reactos/lib/comctl32/propsheet.c +++ b/reactos/lib/comctl32/propsheet.c @@ -131,6 +131,7 @@ typedef struct tagPropSheetInfo int width; int height; HIMAGELIST hImageList; + BOOL ended; } PropSheetInfo; typedef struct @@ -296,7 +297,7 @@ static void PROPSHEET_GetPageRect(const PropSheetInfo * psInfo, HWND hwndDlg, * * Find page index corresponding to page resource id. */ -INT PROPSHEET_FindPageByResId(PropSheetInfo * psInfo, LRESULT resId) +static INT PROPSHEET_FindPageByResId(PropSheetInfo * psInfo, LRESULT resId) { INT i; @@ -707,39 +708,21 @@ int PROPSHEET_CreateDialog(PropSheetInfo* psInfo) * -1 (error). */ if( psInfo->unicode ) { - if (!(psInfo->ppshheader.dwFlags & PSH_MODELESS)) - ret = DialogBoxIndirectParamW(psInfo->ppshheader.hInstance, - (LPDLGTEMPLATEW) temp, - psInfo->ppshheader.hwndParent, - PROPSHEET_DialogProc, - (LPARAM)psInfo); - else - { - ret = (int)CreateDialogIndirectParamW(psInfo->ppshheader.hInstance, - (LPDLGTEMPLATEW) temp, - psInfo->ppshheader.hwndParent, - PROPSHEET_DialogProc, - (LPARAM)psInfo); - if ( !ret ) ret = -1; - } + ret = (int)CreateDialogIndirectParamW(psInfo->ppshheader.hInstance, + (LPDLGTEMPLATEW) temp, + psInfo->ppshheader.hwndParent, + PROPSHEET_DialogProc, + (LPARAM)psInfo); + if ( !ret ) ret = -1; } else { - if (!(psInfo->ppshheader.dwFlags & PSH_MODELESS)) - ret = DialogBoxIndirectParamA(psInfo->ppshheader.hInstance, - (LPDLGTEMPLATEA) temp, - psInfo->ppshheader.hwndParent, - PROPSHEET_DialogProc, - (LPARAM)psInfo); - else - { - ret = (int)CreateDialogIndirectParamA(psInfo->ppshheader.hInstance, - (LPDLGTEMPLATEA) temp, - psInfo->ppshheader.hwndParent, - PROPSHEET_DialogProc, - (LPARAM)psInfo); - if ( !ret ) ret = -1; - } + ret = (int)CreateDialogIndirectParamA(psInfo->ppshheader.hInstance, + (LPDLGTEMPLATEA) temp, + psInfo->ppshheader.hwndParent, + PROPSHEET_DialogProc, + (LPARAM)psInfo); + if ( !ret ) ret = -1; } Free(temp); @@ -1265,7 +1248,7 @@ static BOOL PROPSHEET_CreateTabControl(HWND hwndParent, * Subclassing window procedure for wizard extrior pages to prevent drawing * background and so drawing above the watermark. */ -LRESULT CALLBACK +static LRESULT CALLBACK PROPSHEET_WizardSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uID, DWORD_PTR dwRef) { switch (uMsg) @@ -1757,7 +1740,7 @@ static BOOL PROPSHEET_Finish(HWND hwndDlg) if (psInfo->isModeless) psInfo->activeValid = FALSE; else - EndDialog(hwndDlg, TRUE); + psInfo->ended = TRUE; return TRUE; } @@ -1870,7 +1853,7 @@ static void PROPSHEET_Cancel(HWND hwndDlg, LPARAM lParam) psInfo->activeValid = FALSE; } else - EndDialog(hwndDlg, FALSE); + psInfo->ended = TRUE; } /****************************************************************************** @@ -2396,7 +2379,7 @@ static BOOL PROPSHEET_RemovePage(HWND hwndDlg, psInfo->active_page = -1; if (!psInfo->isModeless) { - EndDialog(hwndDlg, FALSE); + psInfo->ended = TRUE; return TRUE; } } @@ -2737,6 +2720,34 @@ static void PROPSHEET_CleanUp(HWND hwndDlg) GlobalFree((HGLOBAL)psInfo); } +static INT do_loop(PropSheetInfo *psInfo) +{ + MSG msg; + INT ret = -1; + HWND hwnd = psInfo->hwnd; + + while(IsWindow(hwnd) && !psInfo->ended && (ret = GetMessageW(&msg, NULL, 0, 0))) + { + if(ret == -1) + break; + + if(!IsDialogMessageW(hwnd, &msg)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + + if(ret == 0) + { + PostQuitMessage(msg.wParam); + ret = -1; + } + + DestroyWindow(hwnd); + return ret; +} + /****************************************************************************** * PropertySheet (COMCTL32.@) * PropertySheetA (COMCTL32.@) @@ -2787,7 +2798,11 @@ INT WINAPI PropertySheetA(LPCPROPSHEETHEADERA lppsh) } psInfo->unicode = FALSE; + psInfo->ended = FALSE; + bRet = PROPSHEET_CreateDialog(psInfo); + if(!psInfo->isModeless) + bRet = do_loop(psInfo); return bRet; } @@ -2834,7 +2849,11 @@ INT WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh) } psInfo->unicode = TRUE; + psInfo->ended = FALSE; + bRet = PROPSHEET_CreateDialog(psInfo); + if(!psInfo->isModeless) + bRet = do_loop(psInfo); return bRet; } @@ -3039,7 +3058,7 @@ static BOOL PROPSHEET_DoCommand(HWND hwnd, WORD wID) if (psInfo->isModeless) psInfo->activeValid = FALSE; else - EndDialog(hwnd, result); + psInfo->ended = TRUE; } else EnableWindow(hwndApplyBtn, FALSE); @@ -3424,6 +3443,17 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } return TRUE; + case WM_SYSCOMMAND: + switch(wParam & 0xfff0) + { + case SC_CLOSE: + PROPSHEET_Cancel(hwnd, 1); + return TRUE; + + default: + return FALSE; + } + case WM_NOTIFY: { NMHDR* pnmh = (LPNMHDR) lParam; diff --git a/reactos/lib/comctl32/tab.c b/reactos/lib/comctl32/tab.c index 9f4f280819b..927046cfb76 100644 --- a/reactos/lib/comctl32/tab.c +++ b/reactos/lib/comctl32/tab.c @@ -20,17 +20,47 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * NOTES + * + * This code was audited for completeness against the documented features + * of Comctl32.dll version 6.0 on May. 20, 2005, by James Hawkins. + * + * Unless otherwise noted, we believe this code to be complete, as per + * the specification mentioned above. + * If you discover missing features, or bugs, please note them below. + * * TODO: * * Styles: + * TCS_MULTISELECT + * TCS_RIGHT + * TCS_RIGHTJUSTIFY + * TCS_SCROLLOPPOSITE + * TCS_SINGLELINE * TCIF_RTLREADING * + * Extended Styles: + * TCS_EX_FLATSEPARATORS + * TCS_EX_REGISTERDROP + * + * States: + * TCIS_BUTTONPRESSED + * + * Notifications: + * NM_RELEASEDCAPTURE + * TCN_FOCUSCHANGE + * TCN_GETOBJECT + * TCN_KEYDOWN + * * Messages: * TCM_REMOVEIMAGE * TCM_DESELECTALL * TCM_GETEXTENDEDSTYLE * TCM_SETEXTENDEDSTYLE * + * Macros: + * TabCtrl_AdjustRect + * */ #include @@ -1727,14 +1757,20 @@ TAB_DrawItemInterior else drawRect->bottom-=center_offset_h; - center_offset_v = ((drawRect->right - drawRect->left) - (rcText.bottom - rcText.top) + infoPtr->uVItemPadding) / 2; + center_offset_v = ((drawRect->right - drawRect->left) - (rcText.bottom - rcText.top)) / 2; } else { drawRect->left += center_offset_h; - center_offset_v = ((drawRect->bottom - drawRect->top) - (rcText.bottom - rcText.top) + infoPtr->uVItemPadding) / 2; + center_offset_v = ((drawRect->bottom - drawRect->top) - (rcText.bottom - rcText.top)) / 2; } + /* if an item is selected, the text is shifted up instead of down */ + if (iItem == infoPtr->iSelected) + center_offset_v -= infoPtr->uVItemPadding / 2; + else + center_offset_v += infoPtr->uVItemPadding / 2; + if (center_offset_v < 0) center_offset_v = 0; diff --git a/reactos/lib/comctl32/toolbar.c b/reactos/lib/comctl32/toolbar.c index b7406736dc6..53f188490a2 100644 --- a/reactos/lib/comctl32/toolbar.c +++ b/reactos/lib/comctl32/toolbar.c @@ -211,12 +211,13 @@ typedef enum #define DEFPAD_CX 7 #define DEFPAD_CY 6 +#define DEFLISTGAP 4 + +/* vertical padding used in list mode when image is present */ +#define LISTPAD_CY 9 -/* gap between border of button and text/image */ -#define OFFSET_X 1 -#define OFFSET_Y 1 /* how wide to treat the bitmap if it isn't present */ -#define LIST_IMAGE_ABSENT_WIDTH 2 +#define NONLIST_NOTEXT_OFFSET 2 #define TOOLBAR_NOWHERE (-1) @@ -224,11 +225,6 @@ typedef enum #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE) #define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE) -static inline int TOOLBAR_GetListTextOffset(TOOLBAR_INFO *infoPtr, INT iListGap) -{ - return GetSystemMetrics(SM_CXEDGE) + iListGap - infoPtr->szPadding.cx/2; -} - /* Used to find undocumented extended styles */ #define TBSTYLE_EX_ALL (TBSTYLE_EX_DRAWDDARROWS | \ TBSTYLE_EX_UNDOC1 | \ @@ -396,6 +392,14 @@ TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index) } +static inline BOOL +TOOLBAR_IsValidImageList(TOOLBAR_INFO *infoPtr, INT index) +{ + HIMAGELIST himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, index)); + return (himl != NULL) && (ImageList_GetImageCount(himl) > 0); +} + + /*********************************************************************** * TOOLBAR_GetImageListForDrawing * @@ -445,37 +449,6 @@ TOOLBAR_GetImageListForDrawing (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, IMA } -/*********************************************************************** -* TOOLBAR_TestImageExist -* -* This function is similar to TOOLBAR_GetImageListForDrawing, except it does not -* return the image list. The I_IMAGECALLBACK functionality is implemented. -*/ -static BOOL -TOOLBAR_TestImageExist (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl) -{ - INT index; - - if (!himl) return FALSE; - - if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) { - if (btnPtr->iBitmap == I_IMAGENONE) return FALSE; - ERR("index %d is not valid, max %d\n", - btnPtr->iBitmap, infoPtr->nNumBitmaps); - return FALSE; - } - - if ((index = TOOLBAR_GetBitmapIndex(infoPtr, btnPtr)) < 0) { - if ((index == I_IMAGECALLBACK) || - (index == I_IMAGENONE)) return FALSE; - ERR("TBN_GETDISPINFO returned invalid index %d\n", - index); - return FALSE; - } - return TRUE; -} - - static void TOOLBAR_DrawFlatSeparator (LPRECT lpRect, HDC hdc, TOOLBAR_INFO *infoPtr) { @@ -755,7 +728,7 @@ TOOLBAR_DrawImage(TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, INT top /* draws a blank frame for a toolbar button */ static void -TOOLBAR_DrawFrame(const TOOLBAR_INFO *infoPtr, BOOL flat, const NMTBCUSTOMDRAW *tbcd) +TOOLBAR_DrawFrame(const TOOLBAR_INFO *infoPtr, const NMTBCUSTOMDRAW *tbcd) { HDC hdc = tbcd->nmcd.hdc; RECT rc = tbcd->nmcd.rc; @@ -771,7 +744,7 @@ TOOLBAR_DrawFrame(const TOOLBAR_INFO *infoPtr, BOOL flat, const NMTBCUSTOMDRAW * if (infoPtr->dwItemCDFlag & TBCDRF_NOEDGES) return; - if (flat) + if (infoPtr->dwStyle & TBSTYLE_FLAT) { if (pressed_look) DrawEdge (hdc, &rc, BDR_SUNKENOUTER, BF_RECT); @@ -845,7 +818,6 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) rc = btnPtr->rect; CopyRect (&rcArrow, &rc); - CopyRect(&rcBitmap, &rc); /* get a pointer to the text */ lpText = TOOLBAR_GetText(infoPtr, btnPtr); @@ -865,47 +837,51 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) rcArrow.left = right; } - /* copy text rect after adjusting for drop-down arrow - * so that text is centred in the rectangle not containing + /* copy text & bitmap rects after adjusting for drop-down arrow + * so that text & bitmap is centred in the rectangle not containing * the arrow */ CopyRect(&rcText, &rc); + CopyRect(&rcBitmap, &rc); /* Center the bitmap horizontally and vertically */ if (dwStyle & TBSTYLE_LIST) - rcBitmap.left += GetSystemMetrics(SM_CXEDGE); + { + if (lpText && + infoPtr->nMaxTextRows > 0 && + (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || + (btnPtr->fsStyle & BTNS_SHOWTEXT)) ) + rcBitmap.left += GetSystemMetrics(SM_CXEDGE) + infoPtr->szPadding.cx / 2; + else + rcBitmap.left += GetSystemMetrics(SM_CXEDGE) + infoPtr->iListGap / 2; + } else - rcBitmap.left+=(infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2; + rcBitmap.left += (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2; - if(lpText) - rcBitmap.top+= GetSystemMetrics(SM_CYEDGE); - else - rcBitmap.top+=(infoPtr->nButtonHeight - infoPtr->nBitmapHeight) / 2; + rcBitmap.top += infoPtr->szPadding.cy / 2; - TRACE("iBitmap: %d, start=(%ld,%ld) w=%d, h=%d\n", + TRACE("iBitmap=%d, start=(%ld,%ld) w=%d, h=%d\n", btnPtr->iBitmap, rcBitmap.left, rcBitmap.top, infoPtr->nBitmapWidth, infoPtr->nBitmapHeight); - TRACE ("iString: %x\n", btnPtr->iString); - TRACE ("Stringtext: %s\n", debugstr_w(lpText)); + TRACE("Text=%s\n", debugstr_w(lpText)); + TRACE("iListGap=%d, padding = { %ld, %ld }\n", infoPtr->iListGap, infoPtr->szPadding.cx, infoPtr->szPadding.cy); - /* draw text */ - if (lpText) { - rcText.left += GetSystemMetrics(SM_CXEDGE) + OFFSET_X; - rcText.right -= GetSystemMetrics(SM_CXEDGE) + OFFSET_X; - if (GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr,btnPtr->iBitmap)) && - TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) + /* calculate text position */ + if (lpText) + { + rcText.left += GetSystemMetrics(SM_CXEDGE); + rcText.right -= GetSystemMetrics(SM_CXEDGE); + if (dwStyle & TBSTYLE_LIST) { - if (dwStyle & TBSTYLE_LIST) - rcText.left += infoPtr->nBitmapWidth + TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap); - else - rcText.top += GetSystemMetrics(SM_CYEDGE) + OFFSET_Y + infoPtr->nBitmapHeight + infoPtr->szPadding.cy/2; + if (TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) + rcText.left += infoPtr->nBitmapWidth + infoPtr->iListGap + 2; } else - if (dwStyle & TBSTYLE_LIST) - rcText.left += LIST_IMAGE_ABSENT_WIDTH + TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap); - - if (!(infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) && - (btnPtr->fsState & (TBSTATE_PRESSED | TBSTATE_CHECKED))) - OffsetRect(&rcText, 1, 1); + { + if (ImageList_GetImageCount(GETDEFIMAGELIST(infoPtr, 0)) > 0) + rcText.top += infoPtr->szPadding.cy/2 + infoPtr->nBitmapHeight + 1; + else + rcText.top += infoPtr->szPadding.cy/2 + 2; + } } /* Initialize fields in all cases, because we use these later @@ -980,6 +956,10 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) goto FINALNOTIFY; } + if (!(infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) && + (btnPtr->fsState & (TBSTATE_PRESSED | TBSTATE_CHECKED))) + OffsetRect(&rcText, 1, 1); + if (!(tbcd.nmcd.uItemState & CDIS_HOT) && ((tbcd.nmcd.uItemState & CDIS_CHECKED) || (tbcd.nmcd.uItemState & CDIS_INDETERMINATE))) TOOLBAR_DrawPattern (&rc, &tbcd); @@ -998,7 +978,7 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) } } - TOOLBAR_DrawFrame(infoPtr, dwStyle & TBSTYLE_FLAT, &tbcd); + TOOLBAR_DrawFrame(infoPtr, &tbcd); if (drawSepDropDownArrow) TOOLBAR_DrawSepDDArrow(infoPtr, &tbcd, &rcArrow, btnPtr->bDropDownPressed); @@ -1397,6 +1377,166 @@ TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle ) } +/*********************************************************************** +* TOOLBAR_MeasureButton +* +* Calculates the width and height required for a button. Used in +* TOOLBAR_CalcToolbar to set the all-button width and height and also for +* the width of buttons that are autosized. +* +* Note that it would have been rather elegant to use one piece of code for +* both the laying out of the toolbar and for controlling where button parts +* are drawn, but the native control has inconsistencies between the two that +* prevent this from being effectively. These inconsistencies can be seen as +* artefacts where parts of the button appear outside of the bounding button +* rectangle. +* +* There are several cases for the calculation of the button dimensions and +* button part positioning: +* +* List +* ==== +* +* With Bitmap: +* +* +--------------------------------------------------------+ ^ +* | ^ ^ | | +* | | pad.cy / 2 | centred | | +* | pad.cx/2 + cxedge +--------------+ +------------+ | | DEFPAD_CY + +* |<----------------->| nBitmapWidth | | Text | | | max(nBitmapHeight, szText.cy) +* | |<------------>| | | | | +* | +--------------+ +------------+ | | +* |<-------------------------------------->| | | +* | cxedge + iListGap + nBitmapWidth + 2 |<-----------> | | +* | szText.cx | | +* +--------------------------------------------------------+ - +* <--------------------------------------------------------> +* 2*cxedge + nBitmapWidth + iListGap + szText.cx + pad.cx +* +* Without Bitmap (I_IMAGENONE): +* +* +-----------------------------------+ ^ +* | ^ | | +* | | centred | | LISTPAD_CY + +* | +------------+ | | szText.cy +* | | Text | | | +* | | | | | +* | +------------+ | | +* |<----------------->| | | +* | cxedge |<-----------> | | +* | szText.cx | | +* +-----------------------------------+ - +* <-----------------------------------> +* szText.cx + pad.cx +* +* Without text: +* +* +--------------------------------------+ ^ +* | ^ | | +* | | padding.cy/2 | | DEFPAD_CY + +* | +------------+ | | nBitmapHeight +* | | Bitmap | | | +* | | | | | +* | +------------+ | | +* |<------------------->| | | +* | cxedge + iListGap/2 |<-----------> | | +* | nBitmapWidth | | +* +--------------------------------------+ - +* <--------------------------------------> +* 2*cxedge + nBitmapWidth + iListGap +* +* Non-List +* ======== +* +* With bitmap: +* +* +-----------------------------------+ ^ +* | ^ | | +* | | pad.cy / 2 | | nBitmapHeight + +* | - | | szText.cy + +* | +------------+ | | DEFPAD_CY + 1 +* | centred | Bitmap | | | +* |<----------------->| | | | +* | +------------+ | | +* | ^ | | +* | 1 | | | +* | - | | +* | centred +---------------+ | | +* |<--------------->| Text | | | +* | +---------------+ | | +* +-----------------------------------+ - +* <-----------------------------------> +* pad.cx + max(nBitmapWidth, szText.cx) +* +* Without bitmaps (NULL imagelist or ImageList_GetImageCount() = 0): +* +* +---------------------------------------+ ^ +* | ^ | | +* | | 2 + pad.cy / 2 | | +* | - | | szText.cy + +* | centred +-----------------+ | | pad.cy + 2 +* |<--------------->| Text | | | +* | +-----------------+ | | +* | | | +* +---------------------------------------+ - +* <---------------------------------------> +* 2*cxedge + pad.cx + szText.cx +* +* Without text: +* As for with bitmaps, but with szText.cx zero. +*/ +static inline SIZE TOOLBAR_MeasureButton(TOOLBAR_INFO *infoPtr, SIZE sizeString, BOOL bHasBitmap, BOOL bValidImageList) +{ + SIZE sizeButton; + if (infoPtr->dwStyle & TBSTYLE_LIST) + { + /* set button height from bitmap / text height... */ + sizeButton.cy = max((bHasBitmap ? infoPtr->nBitmapHeight : 0), + sizeString.cy); + + /* ... add on the necessary padding */ + if (bValidImageList) + { + if (bHasBitmap) + sizeButton.cy += DEFPAD_CY; + else + sizeButton.cy += LISTPAD_CY; + } + else + sizeButton.cy += infoPtr->szPadding.cy; + + /* calculate button width */ + if (bHasBitmap) + { + sizeButton.cx = 2*GetSystemMetrics(SM_CXEDGE) + + infoPtr->nBitmapWidth + infoPtr->iListGap; + if (sizeString.cx > 0) + sizeButton.cx += sizeString.cx + infoPtr->szPadding.cx; + } + else + sizeButton.cx = sizeString.cx + infoPtr->szPadding.cx; + } + else + { + if (bHasBitmap) + { + sizeButton.cy = infoPtr->nBitmapHeight + 1 + + sizeString.cy + DEFPAD_CY; + sizeButton.cx = infoPtr->szPadding.cx + + max(sizeString.cx, infoPtr->nBitmapWidth); + } + else + { + sizeButton.cy = sizeString.cy + infoPtr->szPadding.cy + + NONLIST_NOTEXT_OFFSET; + sizeButton.cx = 2*GetSystemMetrics(SM_CXEDGE) + + infoPtr->szPadding.cx + sizeString.cx; + } + } + return sizeButton; +} + + /*********************************************************************** * TOOLBAR_CalcToolbar * @@ -1407,7 +1547,6 @@ TOOLBAR_WrapToolbar( HWND hwnd, DWORD dwStyle ) * the tooltip window if appropriate. Finally, it updates the rcBound * rect and calculates the new required toolbar window height. */ - static void TOOLBAR_CalcToolbar (HWND hwnd) { @@ -1416,9 +1555,10 @@ TOOLBAR_CalcToolbar (HWND hwnd) TBUTTON_INFO *btnPtr; INT i, nRows, nSepRows; INT x, y, cx, cy; - SIZE sizeString; + SIZE sizeString, sizeButton; BOOL bWrap; BOOL usesBitmaps = FALSE; + BOOL validImageList = FALSE; BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle); TOOLBAR_CalcStrings (hwnd, &sizeString); @@ -1430,36 +1570,11 @@ TOOLBAR_CalcToolbar (HWND hwnd) if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap)) usesBitmaps = TRUE; } - if (dwStyle & TBSTYLE_LIST) - { - infoPtr->nButtonHeight = max((usesBitmaps) ? infoPtr->nBitmapHeight : - 0, sizeString.cy) + infoPtr->szPadding.cy; - infoPtr->nButtonWidth = ((usesBitmaps) ? infoPtr->nBitmapWidth : - LIST_IMAGE_ABSENT_WIDTH) + sizeString.cx + infoPtr->szPadding.cx; - if (sizeString.cx > 0) - infoPtr->nButtonWidth += TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap) + infoPtr->szPadding.cx/2; - TRACE("LIST style, But w=%d h=%d, useBitmaps=%d, Bit w=%d h=%d\n", - infoPtr->nButtonWidth, infoPtr->nButtonHeight, usesBitmaps, - infoPtr->nBitmapWidth, infoPtr->nBitmapHeight); - } - else { - if (sizeString.cy > 0) - { - if (usesBitmaps) - infoPtr->nButtonHeight = sizeString.cy + - infoPtr->szPadding.cy/2 + /* this is the space to separate text from bitmap */ - infoPtr->nBitmapHeight + infoPtr->szPadding.cy; - else - infoPtr->nButtonHeight = sizeString.cy + infoPtr->szPadding.cy; - } - else - infoPtr->nButtonHeight = infoPtr->nBitmapHeight + infoPtr->szPadding.cy; - - if (sizeString.cx > infoPtr->nBitmapWidth) - infoPtr->nButtonWidth = sizeString.cx + infoPtr->szPadding.cx; - else - infoPtr->nButtonWidth = infoPtr->nBitmapWidth + infoPtr->szPadding.cx; - } + if (TOOLBAR_IsValidImageList(infoPtr, 0)) + validImageList = TRUE; + sizeButton = TOOLBAR_MeasureButton(infoPtr, sizeString, usesBitmaps, validImageList); + infoPtr->nButtonWidth = sizeButton.cx; + infoPtr->nButtonHeight = sizeButton.cy; if ( infoPtr->cxMin >= 0 && infoPtr->nButtonWidth < infoPtr->cxMin ) infoPtr->nButtonWidth = infoPtr->cxMin; @@ -1474,9 +1589,7 @@ TOOLBAR_CalcToolbar (HWND hwnd) /* from above, minimum is a button, and possible text */ cx = infoPtr->nButtonWidth; - /* cannot use just ButtonHeight, we may have no buttons! */ - if (infoPtr->nNumButtons > 0) - infoPtr->nHeight = infoPtr->nButtonHeight; + infoPtr->nHeight = infoPtr->nButtonHeight; cy = infoPtr->nHeight; @@ -1534,22 +1647,10 @@ TOOLBAR_CalcToolbar (HWND hwnd) SelectObject (hdc, hOldFont); ReleaseDC (hwnd, hdc); - /* add space on for button frame, etc */ - cx = sz.cx + infoPtr->szPadding.cx; - - /* add list padding */ - if ((dwStyle & TBSTYLE_LIST) && sz.cx > 0) - cx += TOOLBAR_GetListTextOffset(infoPtr, infoPtr->iListGap) + infoPtr->szPadding.cx/2; - - if (TOOLBAR_TestImageExist (infoPtr, btnPtr, GETDEFIMAGELIST(infoPtr,0))) - { - if (dwStyle & TBSTYLE_LIST) - cx += infoPtr->nBitmapWidth; - else if (cx < (infoPtr->nBitmapWidth+infoPtr->szPadding.cx)) - cx = infoPtr->nBitmapWidth+infoPtr->szPadding.cx; - } - else if (dwStyle & TBSTYLE_LIST) - cx += LIST_IMAGE_ABSENT_WIDTH; + sizeButton = TOOLBAR_MeasureButton(infoPtr, sz, + TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap), + validImageList); + cx = sizeButton.cx; } else cx = infoPtr->nButtonWidth; @@ -4934,10 +5035,11 @@ TOOLBAR_SetHotItemEx (TOOLBAR_INFO *infoPtr, INT nHit, DWORD dwReason) no_highlight = TOOLBAR_SendNotify(&nmhotitem.hdr, infoPtr, TBN_HOTITEMCHANGE); - /* now invalidate the old and new buttons so they will be painted */ - if (oldBtnPtr) + /* now invalidate the old and new buttons so they will be painted, + * but only if they are enabled - disabled buttons cannot become hot */ + if (oldBtnPtr && (oldBtnPtr->fsState & TBSTATE_ENABLED)) InvalidateRect(infoPtr->hwndSelf, &oldBtnPtr->rect, TRUE); - if (btnPtr && !no_highlight) + if (btnPtr && !no_highlight && (btnPtr->fsState & TBSTATE_ENABLED)) { btnPtr->bHot = TRUE; InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE); @@ -4990,8 +5092,8 @@ TOOLBAR_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam) if (!ImageList_GetIconSize(himl, &infoPtr->nBitmapWidth, &infoPtr->nBitmapHeight)) { - infoPtr->nBitmapWidth = 0; - infoPtr->nBitmapHeight = 0; + infoPtr->nBitmapWidth = 1; + infoPtr->nBitmapHeight = 1; } TRACE("hwnd %p, new himl=%p, id = %d, count=%d, bitmap w=%d, h=%d\n", @@ -5089,6 +5191,7 @@ TOOLBAR_SetMaxTextRows (HWND hwnd, WPARAM wParam, LPARAM lParam) * to control the bottom and right borders [with the border being * szPadding.cx - (GetSystemMetrics(SM_CXEDGE)+1)], otherwise the padding * is shared evenly on both sides of the button. + * See blueprints in comments above TOOLBAR_MeasureButton for more info. */ static LRESULT TOOLBAR_SetPadding (HWND hwnd, WPARAM wParam, LPARAM lParam) @@ -5097,8 +5200,8 @@ TOOLBAR_SetPadding (HWND hwnd, WPARAM wParam, LPARAM lParam) DWORD oldPad; oldPad = MAKELONG(infoPtr->szPadding.cx, infoPtr->szPadding.cy); - infoPtr->szPadding.cx = LOWORD((DWORD)lParam); - infoPtr->szPadding.cy = HIWORD((DWORD)lParam); + infoPtr->szPadding.cx = min(LOWORD((DWORD)lParam), GetSystemMetrics(SM_CXEDGE)); + infoPtr->szPadding.cy = min(HIWORD((DWORD)lParam), GetSystemMetrics(SM_CYEDGE)); TRACE("cx=%ld, cy=%ld\n", infoPtr->szPadding.cx, infoPtr->szPadding.cy); return (LRESULT) oldPad; @@ -5487,7 +5590,7 @@ TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam) infoPtr->clrBtnShadow = CLR_DEFAULT; infoPtr->szPadding.cx = DEFPAD_CX; infoPtr->szPadding.cy = DEFPAD_CY; - infoPtr->iListGap = infoPtr->szPadding.cx / 2; + infoPtr->iListGap = DEFLISTGAP; infoPtr->dwStyle = dwStyle; infoPtr->tbim.iButton = -1; GetClientRect(hwnd, &infoPtr->client_rect); diff --git a/reactos/lib/comctl32/treeview.c b/reactos/lib/comctl32/treeview.c index 0bf386c33d9..7ed73042ecc 100644 --- a/reactos/lib/comctl32/treeview.c +++ b/reactos/lib/comctl32/treeview.c @@ -4221,6 +4221,11 @@ TREEVIEW_DoSelectItem(TREEVIEW_INFO *infoPtr, INT action, HTREEITEM newSelect, case TVGN_CARET: prevSelect = infoPtr->selectedItem; + if (prevSelect == newSelect) { + TREEVIEW_EnsureVisible(infoPtr, infoPtr->selectedItem, FALSE); + break; + } + if (TREEVIEW_SendTreeviewNotify(infoPtr, TVN_SELCHANGINGW, cause, diff --git a/reactos/lib/comctl32/updown.c b/reactos/lib/comctl32/updown.c index da2dcc19418..bec0fd007a1 100644 --- a/reactos/lib/comctl32/updown.c +++ b/reactos/lib/comctl32/updown.c @@ -238,7 +238,7 @@ static BOOL UPDOWN_GetArrowFromPoint (UPDOWN_INFO* infoPtr, RECT *rect, POINT pt * UPDOWN_GetThousandSep * Returns the thousand sep. If an error occurs, it returns ','. */ -static WCHAR UPDOWN_GetThousandSep() +static WCHAR UPDOWN_GetThousandSep(void) { WCHAR sep[2];