Sync to Wine-20041019:

Dmitry Timoshkov <dmitry@codeweavers.com>
- If an animation is already playing do not restart it.
- Remove WM_CLOSE handler, it leads to a memory corruption later on.
- Do not use GlobalFree for a memory returned by LoadResource.
Robert Shearman <rob@codeweavers.com>
- Implement SetPathWordBreakProc and MirrorIcon.
- Implement ImageList_SetColorTable.
- Implement WS_DISABLED style.
- Issue EN_CHANGE notification.
- Make the control look more like native by using the right font and
  spacing.
- Use TextOutW rather than DrawTextW as we don't use any features of
  DrawTextW.
- Fix caret size and position.
- Implement WM_CHAR and WM_SYSCHAR messages.
- Status update.
- Should create HOTKEY_INFO storage in WM_NCCREATE rather than in
  WM_CREATE so that we can also add the WS_EX_CLIENTEDGE style.
- Remove code that draws the client edge; it is already drawn by
  DefWindowProc.
- Document status of control against v6.0 of native version.
- Don't use TrackMouseEvents/WM_MOUSELEAVE API for handling the hot
  button; use plain mouse capture instead like native.
- Return only HTTRANSPARENT/HTCLIENT from WM_NCHITTEST and remove
  associated hacks of WM_SETCURSOR, WM_NCLBUTTONDOWN and
  WM_NCLBUTTONUP.
- Refactor state change code so that state changes don't happen as
  side effects from messages such as WM_NCCALCSIZE, instead only from
  user input messages like WM_MOUSEMOVE.
- Rebar completeness audit.
- TBN_DELETINGBUTTON sends the command ID, not the index.
- Fill in tbButton structure for TBN_DELETINGBUTTON notification.
- Document TBN_QUERY* sending indices.
- Fix some TRACEs
- More A->W conversions missed by previous patch.
- Fix off-by-one error in validating drag-n-drop from available
  buttons list box to actual buttons list box.
- Unicode flag should be based on the notification window.
- Use Unicode window messages.
- Determine whether to do label edit before sending NM_CLICK.
Francois Gouget <fgouget@free.fr>
- Don't define COBJMACROS in objbase.h.
- Update the Wine sources accordingly.
- Assorted spelling fixes.
Filip Navara <xnavara@volny.cz>
- Implement PSM_INDEXTOID, PSM_INDEXTOPAGE and PSM_PAGETOINDEX messages.
- Partially implement the PSH_WIZARDCONTEXTHELP and PSH_NOCONTEXTHELP
  styles.
- Add note about unimplemented TB_SAVERESTORE message.
- Fix obviously wrong condition in an "if" statement.
Dimitrie O. Paun <dpaun@rogers.com>
- We now have ICC_LINK_CLASS.
- Cleanup W->A transition.
Jon Griffiths <jon_p_griffiths@yahoo.com>
- ImageList_Merge should not fail if indices are bad.
- Add tests for this case, a visible test mode and fix DrawIndirect test
under some native comctl32.dll's.
- Items are variable sized, use an accessor to get at them.
- Combine A/W calls together to remove duplication.
- Don't leak text when removing/changing items.
- Turn off hot tracking when we delete the last item.
- Use the 'delete 1 item' logic when deleting all items.
- Draw +/- correctly for large icon sizes.
- Item height/expand button width must be >= than imagelist size.
- Avoid a magic number, add FIXME for incorrect +/- drawing.
Michael Stefaniuc <mstefani@redhat.com>
- native ImageList_Remove dosn't spit out an error message when
  deleting an index out of range so don't do that either
- add 2 ImageList_Remove tests
Aric Stewart <aric@codeweavers.com>
- Check to make sure PropSheetInfo* is not null before dereferencing it
for some windows messages.
Vitaliy Margolen <wine-patch@kievinfo.com>
- Don't loose last band on insert.
Ge van Geldorp <gvg@reactos.com>
- Pass correct uiParam for SPI_GETNONCLIENTMETRICS.

svn path=/trunk/; revision=11342
This commit is contained in:
Gé van Geldorp 2004-10-20 08:36:55 +00:00
parent 177b871326
commit 695f33412e
34 changed files with 1142 additions and 1278 deletions

View file

@ -119,7 +119,7 @@ static BOOL ANIMATE_LoadResA(ANIMATE_INFO *infoPtr, HINSTANCE hInst, LPSTR lpNam
mminfo.cchBuffer = SizeofResource(hInst, hrsrc);
infoPtr->hMMio = mmioOpenA(NULL, &mminfo, MMIO_READ);
if (!infoPtr->hMMio) {
GlobalFree((HGLOBAL)lpAvi);
FreeResource(infoPtr->hRes);
return FALSE;
}
@ -414,8 +414,8 @@ static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)
return FALSE;
if (infoPtr->hThread || infoPtr->uTimer) {
FIXME("Already playing ? what should I do ??\n");
ANIMATE_DoStop(infoPtr);
TRACE("Already playing\n");
return TRUE;
}
infoPtr->nFromFrame = (INT)LOWORD(lParam);
@ -443,10 +443,8 @@ static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)
if(GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)
{
HDC hDC = GetDC(hWnd);
infoPtr->hbrushBG = (HBRUSH)SendMessageA(infoPtr->hwndNotify,
WM_CTLCOLORSTATIC, 0, (LPARAM)hWnd);
ReleaseDC(hWnd,hDC);
}
TRACE("Using an animation thread\n");
@ -804,7 +802,7 @@ static LRESULT ANIMATE_Create(HWND hWnd, WPARAM wParam, LPARAM lParam)
InitializeCriticalSection(&infoPtr->cs);
return 0;
return TRUE;
}
@ -860,8 +858,10 @@ static LRESULT WINAPI ANIMATE_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
case ACM_OPENA:
return ANIMATE_OpenA(hWnd, wParam, lParam);
/* case ACM_OPEN32W: FIXME!! */
/* return ANIMATE_Open32W(hWnd, wParam, lParam); */
case ACM_OPENW:
FIXME("ACM_OPENW: stub!\n");
/* return ANIMATE_Open32W(hWnd, wParam, lParam); */
return 0;
case ACM_PLAY:
return ANIMATE_Play(hWnd, wParam, lParam);
@ -870,19 +870,16 @@ static LRESULT WINAPI ANIMATE_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
return ANIMATE_Stop(hWnd, wParam, lParam);
case WM_NCCREATE:
ANIMATE_Create(hWnd, wParam, lParam);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
return ANIMATE_Create(hWnd, wParam, lParam);
case WM_NCHITTEST:
return HTTRANSPARENT;
case WM_DESTROY:
ANIMATE_Destroy(hWnd, wParam, lParam);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
return ANIMATE_Destroy(hWnd, wParam, lParam);
case WM_ERASEBKGND:
ANIMATE_EraseBackground(hWnd, wParam, lParam);
break;
return ANIMATE_EraseBackground(hWnd, wParam, lParam);
/* case WM_STYLECHANGED: FIXME shall we do something ?? */
@ -896,10 +893,6 @@ static LRESULT WINAPI ANIMATE_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
}
return ANIMATE_DrawFrame(ANIMATE_GetInfoPtr(hWnd));
case WM_CLOSE:
ANIMATE_Free(ANIMATE_GetInfoPtr(hWnd));
return TRUE;
case WM_PAINT:
{
ANIMATE_INFO* infoPtr = ANIMATE_GetInfoPtr(hWnd);
@ -940,8 +933,7 @@ static LRESULT WINAPI ANIMATE_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LP
break;
case WM_SIZE:
ANIMATE_Size(hWnd, wParam, lParam);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
return ANIMATE_Size(hWnd, wParam, lParam);
default:
if ((uMsg >= WM_USER) && (uMsg < WM_APP))

View file

@ -130,8 +130,6 @@ static LRESULT WINAPI
COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT WINAPI
COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static int CALLBACK
COMBOEX_PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code);
static LRESULT COMBOEX_Destroy (COMBOEX_INFO *infoPtr);
typedef INT (WINAPI *cmp_func_t)(LPCWSTR, LPCWSTR);
@ -674,11 +672,9 @@ COMBOEX_SetExtendedStyle (COMBOEX_INFO *infoPtr, DWORD mask, DWORD style)
infoPtr->dwExtStyle = style;
/* see if we need to change the word break proc on the edit */
if ((infoPtr->dwExtStyle ^ dwTemp) & CBES_EX_PATHWORDBREAKPROC) {
SendMessageW(infoPtr->hwndEdit, EM_SETWORDBREAKPROC, 0,
(infoPtr->dwExtStyle & CBES_EX_PATHWORDBREAKPROC) ?
(LPARAM)COMBOEX_PathWordBreakProc : 0);
}
if ((infoPtr->dwExtStyle ^ dwTemp) & CBES_EX_PATHWORDBREAKPROC)
SetPathWordBreakProc(infoPtr->hwndEdit,
(infoPtr->dwExtStyle & CBES_EX_PATHWORDBREAKPROC) ? TRUE : FALSE);
/* test if the control's appearance has changed */
mask = CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT;
@ -1650,30 +1646,6 @@ static LRESULT COMBOEX_WindowPosChanging (COMBOEX_INFO *infoPtr, WINDOWPOS *wp)
return 0;
}
static inline int is_delimiter(WCHAR c)
{
switch(c) {
case '/':
case '\\':
case '.':
return TRUE;
}
return FALSE;
}
static int CALLBACK
COMBOEX_PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code)
{
if (code == WB_ISDELIMITER) {
return is_delimiter(lpch[ichCurrent]);
} else {
int dir = (code == WB_LEFT) ? -1 : 1;
for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
if (is_delimiter(lpch[ichCurrent])) return ichCurrent;
}
return ichCurrent;
}
static LRESULT WINAPI
COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

View file

@ -188,4 +188,7 @@ BOOL WINAPI DPA_Merge (const HDPA, const HDPA, DWORD, PFNDPACOMPARE, PFNDPAMERGE
#define DPA_GetPtrCount(hdpa) (*(INT*)(hdpa))
LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet);
BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2);
#endif /* __WINE_COMCTL32_H */

View file

@ -89,13 +89,13 @@
377 stdcall -noname IntlStrEqWorkerW(long wstr wstr long)
382 stdcall -noname SmoothScrollWindow(ptr)
383 stub -noname DoReaderMode
384 stub -noname SetPathWordBreakProc
384 stdcall -noname SetPathWordBreakProc(ptr long)
385 stdcall -noname DPA_EnumCallback(long long long)
386 stdcall -noname DPA_DestroyCallback(ptr ptr long)
387 stdcall -noname DSA_EnumCallback(ptr ptr long)
388 stdcall -noname DSA_DestroyCallback(ptr ptr long)
389 stub -noname SHGetProcessDword
390 stub -noname ImageList_SetColorTable
390 stdcall -noname ImageList_SetColorTable(ptr long long ptr)
400 stdcall -noname CreateMRUListW(ptr)
401 stdcall -noname AddMRUStringW(long wstr)
402 stdcall -noname FindMRUStringW(long wstr ptr)
@ -105,7 +105,7 @@
411 stdcall GetWindowSubclass(long ptr long ptr)
412 stdcall RemoveWindowSubclass(long ptr long)
413 stdcall DefSubclassProc(long long long long)
414 stub -noname MirrorIcon
414 stdcall -noname MirrorIcon(ptr ptr)
415 stdcall DrawTextWrap(long wstr long ptr long) user32.DrawTextW
416 stdcall DrawTextExPrivWrap(long wstr long ptr long ptr) user32.DrawTextExW
417 stdcall ExtTextOutWrap(long long long long ptr wstr long ptr) gdi32.ExtTextOutW

View file

@ -34,8 +34,10 @@
#include <ctype.h>
#include <limits.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"

View file

@ -20,7 +20,7 @@ LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "属性 "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -22,7 +22,7 @@
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Vlastnosti "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -40,7 +40,7 @@ STRINGTABLE DISCARDABLE
}
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Eigenschaften für "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -19,7 +19,7 @@
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Properties for "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -19,7 +19,7 @@
LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Propiedades de "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -23,7 +23,7 @@
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Propriétés pour "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -20,7 +20,7 @@
LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Proprietà per "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -19,7 +19,7 @@
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Properties for "
FONT 9, "MS UI Gothic"
BEGIN

View file

@ -19,7 +19,7 @@
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Properties for "
FONT 9, "MS Shell Dlg"
BEGIN

View file

@ -21,7 +21,7 @@
LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Eigenschappen van "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -20,7 +20,7 @@
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "W³aœciwoœci "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -19,7 +19,7 @@
LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Propriedades para "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -21,7 +21,7 @@
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Ñâîéñòâà äëÿ "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -19,7 +19,7 @@
LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Lastnosti"
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -19,7 +19,7 @@
LANGUAGE LANG_THAI, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "¤Ø³ÊÁºÑµÔ¢Í§ "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -21,7 +21,7 @@
LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
IDD_PROPSHEET DIALOG DISCARDABLE 0, 0, 220, 140
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
STYLE DS_CONTEXTHELP | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Âëàñòèâîñò³ äëÿ "
FONT 8, "MS Shell Dlg"
BEGIN

View file

@ -41,7 +41,7 @@
* -- ICC_DATE_CLASSES
* -- ICC_HOTKEY_CLASS
* -- ICC_INTERNET_CLASSES
* -- ICC_LINK_CLASS (not yet implemented)
* -- ICC_LINK_CLASS
* -- ICC_LISTVIEW_CLASSES
* -- ICC_NATIVEFNTCTL_CLASS
* -- ICC_PAGESCROLLER_CLASS
@ -1485,3 +1485,67 @@ void COMCTL32_DrawInsertMark(HDC hDC, const RECT *lpRect, COLORREF clrInsertMark
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
/***********************************************************************
* MirrorIcon [COMCTL32.414]
*
* Mirrors an icon so that it will appear correctly on a mirrored DC.
*
* PARAMS
* phicon1 [I/O] Icon.
* phicon2 [I/O] Icon.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE.
*/
BOOL WINAPI MirrorIcon(HICON *phicon1, HICON *phicon2)
{
FIXME("(%p, %p): stub\n", phicon1, phicon2);
return FALSE;
}
static inline int IsDelimiter(WCHAR c)
{
switch(c)
{
case '/':
case '\\':
case '.':
case ' ':
return TRUE;
}
return FALSE;
}
static int CALLBACK PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code)
{
if (code == WB_ISDELIMITER)
return IsDelimiter(lpch[ichCurrent]);
else
{
int dir = (code == WB_LEFT) ? -1 : 1;
for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
if (IsDelimiter(lpch[ichCurrent])) return ichCurrent;
}
return ichCurrent;
}
/***********************************************************************
* SetPathWordBreakProc [COMCTL32.384]
*
* Sets the word break procedure for an edit control to one that understands
* paths so that the user can jump over directories.
*
* PARAMS
* hwnd [I] Handle to edit control.
* bSet [I] If this is TRUE then the word break proc is set, otherwise it is removed.
*
* RETURNS
* Result from EM_SETWORDBREAKPROC message.
*/
LRESULT WINAPI SetPathWordBreakProc(HWND hwnd, BOOL bSet)
{
return SendMessageW(hwnd, EM_SETWORDBREAKPROC, 0,
(LPARAM)(bSet ? PathWordBreakProc : NULL));
}

View file

@ -3,6 +3,7 @@
*
* Copyright 1998, 1999 Eric Kohl
* Copyright 2002 Gyorgy 'Nog' Jeney
* Copyright 2004 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -18,8 +19,13 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* TODO:
* - What are we meant to do with the WM_CHAR message?
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Sep. 21, 2004, by Robert Shearman.
*
* 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.
*
*/
#include <stdarg.h>
@ -54,6 +60,7 @@ typedef struct tagHOTKEY_INFO
#define HOTKEY_GetInfoPtr(hwnd) ((HOTKEY_INFO *)GetWindowLongPtrA (hwnd, 0))
static const WCHAR HOTKEY_plussep[] = { ' ', '+', ' ' };
static LRESULT HOTKEY_SetFont (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam);
#define IsOnlySet(flags) (infoPtr->CurrMod == (flags))
@ -87,42 +94,55 @@ HOTKEY_IsCombInv(HOTKEY_INFO *infoPtr)
#undef IsOnlySet
static void
HOTKEY_DrawHotKey(HOTKEY_INFO *infoPtr, LPCWSTR KeyName, WORD NameLen,
LPRECT rc, HDC hdc)
HOTKEY_DrawHotKey(HOTKEY_INFO *infoPtr, LPCWSTR KeyName, WORD NameLen, HDC hdc)
{
SIZE TextSize;
DWORD dwExStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_EXSTYLE);
INT nXStart, nYStart;
COLORREF clrOldText, clrOldBk;
HFONT hFontOld;
/* We have to allow some space for the frame to be drawn */
rc->left += 2;
rc->top++;
DrawTextW(hdc, KeyName, NameLen, rc, DT_LEFT | DT_VCENTER);
rc->left -= 2;
rc->top--;
if(dwExStyle & WS_EX_CLIENTEDGE)
DrawEdge(hdc, rc, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
/* Make a gap from the frame */
nXStart = GetSystemMetrics(SM_CXBORDER);
nYStart = GetSystemMetrics(SM_CYBORDER);
/* Get the text size and position the caret accordingly */
GetTextExtentPoint32W (hdc, KeyName, NameLen, &TextSize);
infoPtr->CaretPos = TextSize.cx + 2;
SetCaretPos(infoPtr->CaretPos, 3);
hFontOld = SelectObject(hdc, infoPtr->hFont);
if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
{
clrOldText = SetTextColor(hdc, comctl32_color.clrGrayText);
clrOldBk = SetBkColor(hdc, comctl32_color.clrBtnFace);
}
else
{
clrOldText = SetTextColor(hdc, comctl32_color.clrWindowText);
clrOldBk = SetBkColor(hdc, comctl32_color.clrWindow);
}
TextOutW(hdc, nXStart, nYStart, KeyName, NameLen);
/* Get the text width for the caret */
GetTextExtentPoint32W(hdc, KeyName, NameLen, &TextSize);
infoPtr->CaretPos = nXStart + TextSize.cx;
SetBkColor(hdc, clrOldBk);
SetTextColor(hdc, clrOldText);
SelectObject(hdc, hFontOld);
/* position the caret */
SetCaretPos(infoPtr->CaretPos, nYStart);
}
/* Draw the names of the keys in the control */
static void
HOTKEY_Refresh(HOTKEY_INFO *infoPtr, HDC hdc)
{
WCHAR KeyName[sizeof(WCHAR) * 64];
WCHAR KeyName[64];
WORD NameLen = 0;
BYTE Modifier;
RECT rc;
GetClientRect(infoPtr->hwndSelf, &rc);
TRACE("(infoPtr=%p hdc=%p)\n", infoPtr, hdc);
if(!infoPtr->CurrMod && !infoPtr->HotKey) {
HOTKEY_DrawHotKey (infoPtr, infoPtr->strNone, 4, &rc, hdc);
HOTKEY_DrawHotKey (infoPtr, infoPtr->strNone, 4, hdc);
return;
}
@ -162,7 +182,7 @@ HOTKEY_Refresh(HOTKEY_INFO *infoPtr, HDC hdc)
else
KeyName[NameLen] = 0;
HOTKEY_DrawHotKey (infoPtr, KeyName, NameLen, &rc, hdc);
HOTKEY_DrawHotKey (infoPtr, KeyName, NameLen, hdc);
}
static void
@ -206,31 +226,13 @@ HOTKEY_SetRules(HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
infoPtr->InvComb, infoPtr->InvMod);
}
/* << HOTKEY_Char >> */
static LRESULT
HOTKEY_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
HOTKEY_Create (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr;
TEXTMETRICW tm;
HDC hdc;
/* allocate memory for info structure */
infoPtr = (HOTKEY_INFO *)Alloc (sizeof(HOTKEY_INFO));
SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
/* initialize info structure */
infoPtr->HotKey = infoPtr->InvComb = infoPtr->InvMod = infoPtr->CurrMod = 0;
infoPtr->CaretPos = 2;
infoPtr->hwndSelf = hwnd;
infoPtr->hwndNotify = ((LPCREATESTRUCTA)lParam)->hwndParent;
LoadStringW(COMCTL32_hModule, HKY_NONE, infoPtr->strNone, 15);
/* get default font height */
hdc = GetDC (hwnd);
GetTextMetricsW (hdc, &tm);
infoPtr->nHeight = tm.tmHeight;
ReleaseDC (hwnd, hdc);
HOTKEY_SetFont(infoPtr, (WPARAM)GetStockObject(SYSTEM_FONT), 0);
return 0;
}
@ -250,18 +252,26 @@ HOTKEY_Destroy (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
static LRESULT
HOTKEY_EraseBackground (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
HBRUSH hBrush;
HBRUSH hBrush, hSolidBrush = NULL;
RECT rc;
hBrush =
(HBRUSH)SendMessageW (infoPtr->hwndNotify, WM_CTLCOLOREDIT,
wParam, (LPARAM)infoPtr->hwndSelf);
if (hBrush)
hBrush = (HBRUSH)GetStockObject (WHITE_BRUSH);
if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
hBrush = hSolidBrush = CreateSolidBrush(comctl32_color.clrBtnFace);
else
{
hBrush = (HBRUSH)SendMessageW(infoPtr->hwndNotify, WM_CTLCOLOREDIT,
wParam, (LPARAM)infoPtr->hwndSelf);
if (!hBrush)
hBrush = hSolidBrush = CreateSolidBrush(comctl32_color.clrWindow);
}
GetClientRect (infoPtr->hwndSelf, &rc);
FillRect ((HDC)wParam, &rc, hBrush);
if (hSolidBrush)
DeleteObject(hSolidBrush);
return -1;
}
@ -275,11 +285,22 @@ HOTKEY_GetFont (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
static LRESULT
HOTKEY_KeyDown (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
WORD wOldHotKey;
BYTE bOldMod;
if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
return 0;
TRACE("() Key: %d\n", wParam);
wOldHotKey = infoPtr->HotKey;
bOldMod = infoPtr->CurrMod;
/* If any key is Pressed, we have to reset the hotkey in the control */
infoPtr->HotKey = 0;
switch (wParam) {
switch (wParam)
{
case VK_RETURN:
case VK_TAB:
case VK_SPACE:
@ -309,7 +330,16 @@ HOTKEY_KeyDown (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
break;
}
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
if ((wOldHotKey != infoPtr->HotKey) || (bOldMod != infoPtr->CurrMod))
{
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
/* send EN_CHANGE notification */
SendMessageW(infoPtr->hwndNotify, WM_COMMAND,
MAKEWPARAM(GetDlgCtrlID(infoPtr->hwndSelf), EN_CHANGE),
(LPARAM)infoPtr->hwndSelf);
}
return 0;
}
@ -317,8 +347,17 @@ HOTKEY_KeyDown (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
static LRESULT
HOTKEY_KeyUp (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
BYTE bOldMod;
if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
return 0;
TRACE("() Key: %d\n", wParam);
switch (wParam) {
bOldMod = infoPtr->CurrMod;
switch (wParam)
{
case VK_SHIFT:
infoPtr->CurrMod &= ~HOTKEYF_SHIFT;
break;
@ -332,7 +371,15 @@ HOTKEY_KeyUp (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
return 1;
}
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
if (bOldMod != infoPtr->CurrMod)
{
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
/* send EN_CHANGE notification */
SendMessageW(infoPtr->hwndNotify, WM_COMMAND,
MAKEWPARAM(GetDlgCtrlID(infoPtr->hwndSelf), EN_CHANGE),
(LPARAM)infoPtr->hwndSelf);
}
return 0;
}
@ -351,18 +398,31 @@ HOTKEY_KillFocus (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
static LRESULT
HOTKEY_LButtonDown (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
SetFocus (infoPtr->hwndSelf);
if (!(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED))
SetFocus (infoPtr->hwndSelf);
return 0;
}
inline static LRESULT
HOTKEY_NCCreate (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
HOTKEY_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
DWORD dwExStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_EXSTYLE);
SetWindowLongW (infoPtr->hwndSelf, GWL_EXSTYLE,
HOTKEY_INFO *infoPtr;
DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
SetWindowLongW (hwnd, GWL_EXSTYLE,
dwExStyle | WS_EX_CLIENTEDGE);
/* allocate memory for info structure */
infoPtr = (HOTKEY_INFO *)Alloc (sizeof(HOTKEY_INFO));
SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);
/* initialize info structure */
infoPtr->HotKey = infoPtr->InvComb = infoPtr->InvMod = infoPtr->CurrMod = 0;
infoPtr->CaretPos = GetSystemMetrics(SM_CXBORDER);
infoPtr->hwndSelf = hwnd;
LoadStringW(COMCTL32_hModule, HKY_NONE, infoPtr->strNone, 15);
return DefWindowProcW (infoPtr->hwndSelf, WM_NCCREATE, wParam, lParam);
}
@ -371,19 +431,15 @@ HOTKEY_SetFocus (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
infoPtr->bFocus = TRUE;
CreateCaret (infoPtr->hwndSelf, NULL, 1, infoPtr->nHeight - 2);
SetCaretPos (infoPtr->CaretPos, 3);
CreateCaret (infoPtr->hwndSelf, NULL, 1, infoPtr->nHeight);
SetCaretPos (infoPtr->CaretPos, GetSystemMetrics(SM_CYBORDER));
ShowCaret (infoPtr->hwndSelf);
return 0;
}
inline static LRESULT
static LRESULT
HOTKEY_SetFont (HOTKEY_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
TEXTMETRICW tm;
@ -414,7 +470,7 @@ HOTKEY_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
if (!infoPtr && (uMsg != WM_CREATE))
if (!infoPtr && (uMsg != WM_NCCREATE))
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
switch (uMsg)
{
@ -427,10 +483,12 @@ HOTKEY_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
HOTKEY_SetRules (infoPtr, wParam, lParam);
break;
/* case WM_CHAR: */
case WM_CHAR:
case WM_SYSCHAR:
return HOTKEY_KeyDown (infoPtr, MapVirtualKeyW(LOBYTE(HIWORD(lParam)), 1), lParam);
case WM_CREATE:
return HOTKEY_Create (hwnd, wParam, lParam);
return HOTKEY_Create (infoPtr, wParam, lParam);
case WM_DESTROY:
return HOTKEY_Destroy (infoPtr, wParam, lParam);
@ -459,7 +517,7 @@ HOTKEY_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return HOTKEY_LButtonDown (infoPtr, wParam, lParam);
case WM_NCCREATE:
return HOTKEY_NCCreate (infoPtr, wParam, lParam);
return HOTKEY_NCCreate (hwnd, wParam, lParam);
case WM_PAINT:
HOTKEY_Paint(infoPtr, (HDC)wParam);
@ -471,8 +529,6 @@ HOTKEY_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_SETFONT:
return HOTKEY_SetFont (infoPtr, wParam, lParam);
/* case WM_SYSCHAR: */
default:
if ((uMsg >= WM_USER) && (uMsg < WM_APP))
ERR("unknown msg %04x wp=%08x lp=%08lx\n",
@ -490,7 +546,7 @@ HOTKEY_Register (void)
ZeroMemory (&wndClass, sizeof(WNDCLASSW));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = (WNDPROC)HOTKEY_WindowProc;
wndClass.lpfnWndProc = HOTKEY_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(HOTKEY_INFO *);
wndClass.hCursor = 0;

View file

@ -39,6 +39,9 @@
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#define COBJMACROS
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
@ -584,7 +587,7 @@ ImageList_Create (INT cx, INT cy, UINT flags,
goto cleanup;
}
/* Default to ILC_COLOR4 if non of the ILC_COLOR* flags are specified */
/* Default to ILC_COLOR4 if none of the ILC_COLOR* flags are specified */
if (ilc == ILC_COLOR)
ilc = ILC_COLOR4;
@ -1716,8 +1719,7 @@ ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow,
/*************************************************************************
* ImageList_Merge [COMCTL32.@]
*
* Creates a new image list that contains a merged image from the specified
* images of both source image lists.
* Create an image list containing a merged image from two image lists.
*
* PARAMS
* himl1 [I] handle to first image list
@ -1728,10 +1730,16 @@ ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow,
* dy [I] Y offset of the second image relative to the first.
*
* RETURNS
* Success: handle of the merged image list.
* Failure: NULL
* Success: The newly created image list. It contains a single image
* consisting of the second image merged with the first.
* Failure: NULL, if either himl1 or himl2 are invalid.
*
* NOTES
* - The returned image list should be deleted by the caller using
* ImageList_Destroy() when it is no longer required.
* - If either i1 or i2 are not valid image indices they will be treated
* as a blank image.
*/
HIMAGELIST WINAPI
ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
INT dx, INT dy)
@ -1747,17 +1755,6 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
if (!is_valid(himl1) || !is_valid(himl2))
return NULL;
/* check indices */
if ((i1 < 0) || (i1 >= himl1->cCurImage)) {
ERR("Index 1 out of range! %d\n", i1);
return NULL;
}
if ((i2 < 0) || (i2 >= himl2->cCurImage)) {
ERR("Index 2 out of range! %d\n", i2);
return NULL;
}
if (dx > 0) {
cxDst = max (himl1->cx, dx + himl2->cx);
xOff1 = 0;
@ -1791,23 +1788,28 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
}
himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | ILC_COLOR, 1, 1);
if (!himlDst)
return NULL;
if (himlDst) {
if (himlDst)
{
nX1 = i1 * himl1->cx;
nX2 = i2 * himl2->cx;
/* copy image */
BitBlt (himlDst->hdcImage, 0, 0, cxDst, cyDst, himl1->hdcImage, 0, 0, BLACKNESS);
BitBlt (himlDst->hdcImage, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcImage, nX1, 0, SRCCOPY);
BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask , nX2, 0, SRCAND);
BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, nX2, 0, SRCPAINT);
BitBlt (himlDst->hdcImage, 0, 0, cxDst, cyDst, himl1->hdcImage, 0, 0, BLACKNESS);
if (i1 >= 0 && i1 < himl1->cCurImage)
BitBlt (himlDst->hdcImage, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcImage, nX1, 0, SRCCOPY);
if (i2 >= 0 && i2 < himl2->cCurImage)
{
BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask , nX2, 0, SRCAND);
BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, nX2, 0, SRCPAINT);
}
/* copy mask */
BitBlt (himlDst->hdcMask, 0, 0, cxDst, cyDst, himl1->hdcMask, 0, 0, WHITENESS);
BitBlt (himlDst->hdcMask, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcMask, nX1, 0, SRCCOPY);
BitBlt (himlDst->hdcMask, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask, nX2, 0, SRCAND);
BitBlt (himlDst->hdcMask, 0, 0, cxDst, cyDst, himl1->hdcMask, 0, 0, WHITENESS);
if (i1 >= 0 && i1 < himl1->cCurImage)
BitBlt (himlDst->hdcMask, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcMask, nX1, 0, SRCCOPY);
if (i2 >= 0 && i2 < himl2->cCurImage)
BitBlt (himlDst->hdcMask, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask, nX2, 0, SRCAND);
himlDst->cCurImage = 1;
}
@ -2052,7 +2054,7 @@ ImageList_Remove (HIMAGELIST himl, INT i)
}
if ((i < -1) || (i >= himl->cCurImage)) {
ERR("index out of range! %d\n", i);
TRACE("index out of range! %d\n", i);
return FALSE;
}
@ -2247,7 +2249,7 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
ICONINFO ii;
BITMAP bmp;
TRACE("(0x%lx 0x%x %p)\n", (DWORD)himl, i, hIcon);
TRACE("(%p %d %p)\n", himl, i, hIcon);
if (!is_valid(himl))
return -1;
@ -2305,6 +2307,7 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
if (ii.hbmMask)
DeleteObject (ii.hbmMask);
TRACE("Insert index = %d, himl->cCurImage = %d\n", nIndex, himl->cCurImage);
return nIndex;
}
@ -2850,6 +2853,31 @@ static HBITMAP ImageList_CreateImage(HDC hdc, HIMAGELIST himl, UINT width, UINT
hbmNewBitmap = CreateBitmap (width, height, 1, himl->uBitsPixel, NULL);
}
TRACE("returning %p\n", hbmNewBitmap);
return hbmNewBitmap;
}
/*************************************************************************
* ImageList_SetColorTable [COMCTL32.@]
*
* Sets the color table of an image list.
*
* PARAMS
* himl [I] Handle to the image list.
* uStartIndex [I] The first index to set.
* cEntries [I] Number of entries to set.
* prgb [I] New color information for color table for the image list.
*
* RETURNS
* Success: Number of entries in the table that were set.
* Failure: Zero.
*
* SEE
* ImageList_Create(), SetDIBColorTable()
*/
UINT WINAPI
ImageList_SetColorTable (HIMAGELIST himl, UINT uStartIndex, UINT cEntries, CONST RGBQUAD * prgb)
{
return SetDIBColorTable(himl->hdcImage, uStartIndex, cEntries, prgb);
}

View file

@ -21,11 +21,21 @@
* Tested primarily with the controlspy Pager application.
* Susan Farley (susan@codeweavers.com)
*
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Sep. 18, 2004, by Robert Shearman.
*
* 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:
* Implement repetitive button press.
* Adjust arrow size relative to size of button.
* Allow border size changes.
* Implement drag and drop style.
* Styles:
* PGS_DRAGNDROP
* Notifications:
* PGN_HOTITEMCHANGE
*/
#include <stdarg.h>
@ -70,6 +80,34 @@ typedef struct
#define INITIAL_DELAY 500
#define REPEAT_DELAY 50
static void
PAGER_GetButtonRects(HWND hwnd, PAGER_INFO* infoPtr, RECT* prcTopLeft, RECT* prcBottomRight, BOOL bClientCoords)
{
RECT rcWindow;
GetWindowRect (hwnd, &rcWindow);
if (bClientCoords)
{
POINT pt = {rcWindow.left, rcWindow.top};
ScreenToClient(hwnd, &pt);
OffsetRect(&rcWindow, -(rcWindow.left-pt.x), -(rcWindow.top-pt.y));
}
else
OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
*prcTopLeft = *prcBottomRight = rcWindow;
if (PAGER_IsHorizontal(hwnd))
{
prcTopLeft->right = prcTopLeft->left + infoPtr->nButtonSize;
prcBottomRight->left = prcBottomRight->right - infoPtr->nButtonSize;
}
else
{
prcTopLeft->bottom = prcTopLeft->top + infoPtr->nButtonSize;
prcBottomRight->top = prcBottomRight->bottom - infoPtr->nButtonSize;
}
}
/* the horizontal arrows are:
*
* 01234 01234
@ -178,7 +216,9 @@ PAGER_DrawButton(HDC hdc, COLORREF clrBk, RECT arrowRect,
HBRUSH hBrush, hOldBrush;
RECT rc = arrowRect;
if (!btnState) /* PGF_INVISIBLE */
TRACE("arrowRect = %s, btnState = %d\n", wine_dbgstr_rect(&arrowRect), btnState);
if (btnState == PGF_INVISIBLE)
return;
if ((rc.right - rc.left <= 0) || (rc.bottom - rc.top <= 0))
@ -234,33 +274,6 @@ PAGER_DrawButton(HDC hdc, COLORREF clrBk, RECT arrowRect,
DeleteObject(hBrush);
}
static void PAGER_CaptureandTrack(PAGER_INFO *infoPtr, HWND hwnd)
{
TRACKMOUSEEVENT trackinfo;
TRACE("[%p] SetCapture\n", hwnd);
SetCapture(hwnd);
infoPtr->bCapture = TRUE;
trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
trackinfo.dwFlags = TME_QUERY;
trackinfo.hwndTrack = hwnd;
trackinfo.dwHoverTime = HOVER_DEFAULT;
/* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
_TrackMouseEvent(&trackinfo);
/* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
if(!(trackinfo.dwFlags & TME_LEAVE)) {
trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
/* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
/* and can properly deactivate the hot button */
_TrackMouseEvent(&trackinfo);
}
}
/* << PAGER_GetDropTarget >> */
static inline LRESULT
@ -424,96 +437,61 @@ PAGER_GetScrollRange(HWND hwnd, PAGER_INFO* infoPtr)
return scrollRange;
}
static void
PAGER_GrayAndRestoreBtns(PAGER_INFO* infoPtr, INT scrollRange,
BOOL* needsResize, BOOL* needsRepaint)
{
if (infoPtr->nPos > 0)
{
*needsResize |= !infoPtr->TLbtnState; /* PGF_INVISIBLE */
if (infoPtr->TLbtnState != PGF_DEPRESSED)
infoPtr->TLbtnState = PGF_NORMAL;
}
else
{
*needsRepaint |= (infoPtr->TLbtnState != PGF_GRAYED);
infoPtr->TLbtnState = PGF_GRAYED;
}
if (scrollRange <= 0)
{
*needsRepaint |= (infoPtr->TLbtnState != PGF_GRAYED);
infoPtr->TLbtnState = PGF_GRAYED;
*needsRepaint |= (infoPtr->BRbtnState != PGF_GRAYED);
infoPtr->BRbtnState = PGF_GRAYED;
}
else if (infoPtr->nPos < scrollRange)
{
*needsResize |= !infoPtr->BRbtnState; /* PGF_INVISIBLE */
if (infoPtr->BRbtnState != PGF_DEPRESSED)
infoPtr->BRbtnState = PGF_NORMAL;
}
else
{
*needsRepaint |= (infoPtr->BRbtnState != PGF_GRAYED);
infoPtr->BRbtnState = PGF_GRAYED;
}
}
static void
PAGER_NormalizeBtns(PAGER_INFO* infoPtr, BOOL* needsRepaint)
{
if (infoPtr->TLbtnState & (PGF_HOT | PGF_DEPRESSED))
{
infoPtr->TLbtnState = PGF_NORMAL;
*needsRepaint = TRUE;
}
if (infoPtr->BRbtnState & (PGF_HOT | PGF_DEPRESSED))
{
infoPtr->BRbtnState = PGF_NORMAL;
*needsRepaint = TRUE;
}
}
static void
PAGER_HideGrayBtns(PAGER_INFO* infoPtr, BOOL* needsResize)
{
if (infoPtr->TLbtnState == PGF_GRAYED)
{
infoPtr->TLbtnState = PGF_INVISIBLE;
*needsResize = TRUE;
}
if (infoPtr->BRbtnState == PGF_GRAYED)
{
infoPtr->BRbtnState = PGF_INVISIBLE;
*needsResize = TRUE;
}
}
static void
PAGER_UpdateBtns(HWND hwnd, PAGER_INFO *infoPtr,
INT scrollRange, BOOL hideGrayBtns)
{
BOOL resizeClient = FALSE;
BOOL repaintBtns = FALSE;
BOOL resizeClient;
BOOL repaintBtns;
INT oldTLbtnState = infoPtr->TLbtnState;
INT oldBRbtnState = infoPtr->BRbtnState;
POINT pt;
RECT rcTopLeft, rcBottomRight;
if (scrollRange < 0)
PAGER_NormalizeBtns(infoPtr, &repaintBtns);
/* get button rects */
PAGER_GetButtonRects(hwnd, infoPtr, &rcTopLeft, &rcBottomRight, FALSE);
GetCursorPos(&pt);
/* update states based on scroll position */
if (infoPtr->nPos > 0)
{
if (infoPtr->TLbtnState == PGF_INVISIBLE || infoPtr->TLbtnState == PGF_GRAYED)
infoPtr->TLbtnState = PGF_NORMAL;
}
else if (PtInRect(&rcTopLeft, pt))
infoPtr->TLbtnState = PGF_GRAYED;
else
PAGER_GrayAndRestoreBtns(infoPtr, scrollRange, &resizeClient, &repaintBtns);
infoPtr->TLbtnState = PGF_INVISIBLE;
if (hideGrayBtns)
PAGER_HideGrayBtns(infoPtr, &resizeClient);
if (scrollRange <= 0)
{
infoPtr->TLbtnState = PGF_INVISIBLE;
infoPtr->BRbtnState = PGF_INVISIBLE;
}
else if (infoPtr->nPos < scrollRange)
{
if (infoPtr->BRbtnState == PGF_INVISIBLE || infoPtr->BRbtnState == PGF_GRAYED)
infoPtr->BRbtnState = PGF_NORMAL;
}
else if (PtInRect(&rcBottomRight, pt))
infoPtr->BRbtnState = PGF_GRAYED;
else
infoPtr->BRbtnState = PGF_INVISIBLE;
if (resizeClient) /* initiate NCCalcSize to resize client wnd */ {
/* only need to resize when entering or leaving PGF_INVISIBLE state */
resizeClient =
((oldTLbtnState == PGF_INVISIBLE) != (infoPtr->TLbtnState == PGF_INVISIBLE)) ||
((oldBRbtnState == PGF_INVISIBLE) != (infoPtr->BRbtnState == PGF_INVISIBLE));
/* initiate NCCalcSize to resize client wnd if necessary */
if (resizeClient)
SetWindowPos(hwnd, 0,0,0,0,0,
SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOZORDER | SWP_NOACTIVATE);
}
/* repaint when changing any state */
repaintBtns = (oldTLbtnState != infoPtr->TLbtnState) ||
(oldBRbtnState != infoPtr->BRbtnState);
if (repaintBtns)
SendMessageW(hwnd, WM_NCPAINT, 0, 0);
}
@ -667,10 +645,7 @@ PAGER_RecalcSize(HWND hwnd)
PAGER_SetPos(hwnd, 0, FALSE);
}
else
{
PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, TRUE);
PAGER_PositionChildWnd(hwnd, infoPtr);
}
}
return 1;
@ -891,10 +866,7 @@ PAGER_NCCalcSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
LPRECT lpRect = (LPRECT)lParam;
RECT rcChildw, rcmyw, wnrc, ltrc, rbrc;
POINT cursor;
BOOL resizeClient = FALSE;
BOOL repaintBtns = FALSE;
RECT rcChild, rcWindow;
INT scrollRange;
/*
@ -906,43 +878,19 @@ PAGER_NCCalcSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
DefWindowProcW (hwnd, WM_NCCALCSIZE, wParam, lParam);
TRACE("orig rect=(%ld,%ld)-(%ld,%ld)\n",
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
TRACE("orig rect=%s\n", wine_dbgstr_rect(lpRect));
GetWindowRect (infoPtr->hwndChild, &rcChild);
MapWindowPoints (0, hwnd, (LPPOINT)&rcChild, 2); /* FIXME: RECT != 2 POINTS */
GetWindowRect (hwnd, &rcWindow);
if (PAGER_IsHorizontal(hwnd))
{
infoPtr->nWidth = lpRect->right - lpRect->left;
PAGER_CalcSize (hwnd, &infoPtr->nWidth, TRUE);
GetWindowRect (infoPtr->hwndChild, &rcChildw);
MapWindowPoints (0, hwnd, (LPPOINT)&rcChildw, 2);
GetCursorPos (&cursor);
GetWindowRect (hwnd, &rcmyw);
/* Reset buttons and hide any grey ones */
scrollRange = infoPtr->nWidth - (rcmyw.right - rcmyw.left);
scrollRange = infoPtr->nWidth - (rcWindow.right - rcWindow.left);
TRACE("nPos=%d, scrollrange=%d, nHeigth=%d, myw=(%ld,%ld)-(%ld,%ld), cursor=(%ld,%ld)\n",
infoPtr->nPos, scrollRange, infoPtr->nHeight,
rcmyw.left, rcmyw.top,
rcmyw.right, rcmyw.bottom,
cursor.x, cursor.y);
PAGER_GrayAndRestoreBtns(infoPtr, scrollRange, &resizeClient, &repaintBtns);
PAGER_HideGrayBtns(infoPtr, &resizeClient);
if (PtInRect (&rcmyw, cursor)) {
GetWindowRect (hwnd, &wnrc);
ltrc = wnrc;
ltrc.right = ltrc.left + infoPtr->nButtonSize;
rbrc = wnrc;
rbrc.left = rbrc.right - infoPtr->nButtonSize;
TRACE("horz lt rect=(%ld,%ld)-(%ld,%ld), rb rect=(%ld,%ld)-(%ld,%ld)\n",
ltrc.left, ltrc.top, ltrc.right, ltrc.bottom,
rbrc.left, rbrc.top, rbrc.right, rbrc.bottom);
if (PtInRect (&ltrc, cursor) && infoPtr->TLbtnState)
RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE);
if (PtInRect (&rbrc, cursor) && infoPtr->BRbtnState)
RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE);
}
if (infoPtr->TLbtnState && (lpRect->left + infoPtr->nButtonSize < lpRect->right))
lpRect->left += infoPtr->nButtonSize;
if (infoPtr->BRbtnState && (lpRect->right - infoPtr->nButtonSize > lpRect->left))
@ -950,65 +898,21 @@ PAGER_NCCalcSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
}
else
{
/* native does: (from trace of IE4 opening "Favorites" frame)
* DefWindowProc
* WM_NOITFY PGN_CALCSIZE w/ dwFlag=2
* GetWindowRect (child, &rc)
* MapWindowPoints (0, syspager, &rc, 2)
* GetCursorPos( &cur )
* GetWindowRect (syspager, &rc2)
* PtInRect (&rc2, cur.x, cur.y) rtns 0
* returns with rect empty
*/
infoPtr->nHeight = lpRect->bottom - lpRect->top;
PAGER_CalcSize (hwnd, &infoPtr->nHeight, FALSE);
GetWindowRect (infoPtr->hwndChild, &rcChildw);
MapWindowPoints (0, hwnd, (LPPOINT)&rcChildw, 2);
GetCursorPos (&cursor);
GetWindowRect (hwnd, &rcmyw);
/* Reset buttons and hide any grey ones */
scrollRange = infoPtr->nHeight - (rcmyw.bottom - rcmyw.top);
scrollRange = infoPtr->nHeight - (rcWindow.bottom - rcWindow.top);
TRACE("nPos=%d, scrollrange=%d, nHeigth=%d, myw=(%ld,%ld)-(%ld,%ld), cursor=(%ld,%ld)\n",
infoPtr->nPos, scrollRange, infoPtr->nHeight,
rcmyw.left, rcmyw.top,
rcmyw.right, rcmyw.bottom,
cursor.x, cursor.y);
PAGER_GrayAndRestoreBtns(infoPtr, scrollRange, &resizeClient, &repaintBtns);
PAGER_HideGrayBtns(infoPtr, &resizeClient);
if (PtInRect (&rcmyw, cursor)) {
/* native does:
* GetWindowRect(pager, &rc)
* PtInRect(btn-left????, cur.x, cur.y)
* if true -> ???
* PtInRect(btn-right????, cur.x, cur.y)
* if true
* RedrawWindow(pager, 0, 0, 5)
* return TRUE
*/
GetWindowRect (hwnd, &wnrc);
ltrc = wnrc;
ltrc.right = ltrc.left + infoPtr->nButtonSize;
rbrc = wnrc;
rbrc.left = rbrc.right - infoPtr->nButtonSize;
TRACE("vert lt rect=(%ld,%ld)-(%ld,%ld), rb rect=(%ld,%ld)-(%ld,%ld)\n",
ltrc.left, ltrc.top, ltrc.right, ltrc.bottom,
rbrc.left, rbrc.top, rbrc.right, rbrc.bottom);
if (PtInRect (&ltrc, cursor) && infoPtr->TLbtnState)
RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE);
if (PtInRect (&rbrc, cursor) && infoPtr->BRbtnState)
RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE);
}
if (infoPtr->TLbtnState && (lpRect->top + infoPtr->nButtonSize < lpRect->bottom))
lpRect->top += infoPtr->nButtonSize;
if (infoPtr->BRbtnState && (lpRect->bottom - infoPtr->nButtonSize > lpRect->top))
lpRect->bottom -= infoPtr->nButtonSize;
}
TRACE("nPos=%d, nHeigth=%d, window=%s\n",
infoPtr->nPos, infoPtr->nHeight,
wine_dbgstr_rect(&rcWindow));
TRACE("[%p] client rect set to %ldx%ld at (%ld,%ld) BtnState[%d,%d]\n",
hwnd, lpRect->right-lpRect->left, lpRect->bottom-lpRect->top,
lpRect->left, lpRect->top,
@ -1022,7 +926,7 @@ PAGER_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
PAGER_INFO* infoPtr = PAGER_GetInfoPtr(hwnd);
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
RECT rcWindow, rcBottomRight, rcTopLeft;
RECT rcBottomRight, rcTopLeft;
HDC hdc;
BOOL bHorizontal = PAGER_IsHorizontal(hwnd);
@ -1034,20 +938,7 @@ PAGER_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
return 0;
GetWindowRect (hwnd, &rcWindow);
OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
rcTopLeft = rcBottomRight = rcWindow;
if (bHorizontal)
{
rcTopLeft.right = rcTopLeft.left + infoPtr->nButtonSize;
rcBottomRight.left = rcBottomRight.right - infoPtr->nButtonSize;
}
else
{
rcTopLeft.bottom = rcTopLeft.top + infoPtr->nButtonSize;
rcBottomRight.top = rcBottomRight.bottom - infoPtr->nButtonSize;
}
PAGER_GetButtonRects(hwnd, infoPtr, &rcTopLeft, &rcBottomRight, FALSE);
PAGER_DrawButton(hdc, infoPtr->clrBk, rcTopLeft,
bHorizontal, TRUE, infoPtr->TLbtnState);
@ -1059,135 +950,52 @@ PAGER_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
static INT
PAGER_HitTest (HWND hwnd, LPPOINT pt)
PAGER_HitTest (HWND hwnd, const POINT * pt)
{
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
RECT clientRect;
BOOL bHorizontal = PAGER_IsHorizontal(hwnd);
RECT clientRect, rcTopLeft, rcBottomRight;
POINT ptWindow;
GetClientRect (hwnd, &clientRect);
if (PtInRect(&clientRect, *pt))
{
TRACE("HTCLIENT\n");
return HTCLIENT;
TRACE("child\n");
return -1;
}
if (infoPtr->TLbtnState && infoPtr->TLbtnState != PGF_GRAYED)
ptWindow = *pt;
PAGER_GetButtonRects(hwnd, infoPtr, &rcTopLeft, &rcBottomRight, TRUE);
if ((infoPtr->TLbtnState != PGF_INVISIBLE) && PtInRect(&rcTopLeft, ptWindow))
{
if (bHorizontal)
{
if (pt->x < clientRect.left)
{
TRACE("HTLEFT\n");
return HTLEFT;
}
}
else
{
if (pt->y < clientRect.top)
{
TRACE("HTTOP\n");
return HTTOP;
}
}
TRACE("PGB_TOPORLEFT\n");
return PGB_TOPORLEFT;
}
if (infoPtr->BRbtnState && infoPtr->BRbtnState != PGF_GRAYED)
else if ((infoPtr->BRbtnState != PGF_INVISIBLE) && PtInRect(&rcBottomRight, ptWindow))
{
if (bHorizontal)
{
if (pt->x > clientRect.right)
{
TRACE("HTRIGHT\n");
return HTRIGHT;
}
}
else
{
if (pt->y > clientRect.bottom)
{
TRACE("HTBOTTOM\n");
return HTBOTTOM;
}
}
TRACE("PGB_BOTTOMORRIGHT\n");
return PGB_BOTTOMORRIGHT;
}
TRACE("HTNOWHERE\n");
return HTNOWHERE;
TRACE("nowhere\n");
return -1;
}
static LRESULT
PAGER_NCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
POINT pt;
INT nHit;
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
ScreenToClient (hwnd, &pt);
return PAGER_HitTest(hwnd, &pt);
}
static LRESULT
PAGER_SetCursor( HWND hwnd, WPARAM wParam, LPARAM lParam )
{
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
BOOL notCaptured = FALSE;
switch(LOWORD(lParam))
{
case HTLEFT:
case HTTOP:
if ((notCaptured = infoPtr->TLbtnState != PGF_HOT))
infoPtr->TLbtnState = PGF_HOT;
break;
case HTRIGHT:
case HTBOTTOM:
if ((notCaptured = infoPtr->BRbtnState != PGF_HOT))
infoPtr->BRbtnState = PGF_HOT;
break;
default:
return FALSE;
}
if (notCaptured)
{
PAGER_CaptureandTrack(infoPtr, hwnd);
SendMessageW(hwnd, WM_NCPAINT, 0, 0);
}
return TRUE;
}
static LRESULT
PAGER_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
KillTimer (hwnd, TIMERID1);
KillTimer (hwnd, TIMERID2);
TRACE("[%p] ReleaseCapture\n", hwnd);
ReleaseCapture();
infoPtr->bCapture = FALSE;
/* Notify parent of released mouse capture */
{
NMHDR nmhdr;
ZeroMemory (&nmhdr, sizeof (NMHDR));
nmhdr.hwndFrom = hwnd;
nmhdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
nmhdr.code = NM_RELEASEDCAPTURE;
SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}
/* make HOT btns NORMAL and hide gray btns */
PAGER_UpdateBtns(hwnd, infoPtr, -1, TRUE);
return TRUE;
nHit = PAGER_HitTest(hwnd, &pt);
if (nHit < 0)
return HTTRANSPARENT;
return HTCLIENT;
}
static LRESULT
@ -1195,7 +1003,7 @@ PAGER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
POINT clpt, pt;
RECT wnrect, TLbtnrect, BRbtnrect, *btnrect = NULL;
RECT wnrect, *btnrect = NULL;
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
BOOL topLeft = FALSE;
INT btnstate = 0;
@ -1209,75 +1017,103 @@ PAGER_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
ClientToScreen(hwnd, &pt);
GetWindowRect(hwnd, &wnrect);
if (PtInRect(&wnrect, pt)) {
TLbtnrect = wnrect;
BRbtnrect = wnrect;
if (dwStyle & PGS_HORZ) {
TLbtnrect.right = TLbtnrect.left + infoPtr->nButtonSize;
BRbtnrect.left = BRbtnrect.right - infoPtr->nButtonSize;
}
else {
TLbtnrect.bottom = TLbtnrect.top + infoPtr->nButtonSize;
BRbtnrect.top = BRbtnrect.bottom - infoPtr->nButtonSize;
}
RECT TLbtnrect, BRbtnrect;
PAGER_GetButtonRects(hwnd, infoPtr, &TLbtnrect, &BRbtnrect, FALSE);
clpt = pt;
MapWindowPoints(0, hwnd, &clpt, 1);
hit = PAGER_HitTest(hwnd, &clpt);
if (hit == HTLEFT || hit == HTTOP) {
if ((hit == PGB_TOPORLEFT) && (infoPtr->TLbtnState == PGF_NORMAL))
{
topLeft = TRUE;
btnrect = &TLbtnrect;
infoPtr->TLbtnState = PGF_DEPRESSED;
infoPtr->TLbtnState = PGF_HOT;
btnstate = infoPtr->TLbtnState;
}
else if (hit == HTRIGHT || hit == HTBOTTOM) {
else if ((hit == PGB_BOTTOMORRIGHT) && (infoPtr->BRbtnState == PGF_NORMAL))
{
topLeft = FALSE;
btnrect = &BRbtnrect;
infoPtr->BRbtnState = PGF_DEPRESSED;
infoPtr->BRbtnState = PGF_HOT;
btnstate = infoPtr->BRbtnState;
}
/* If in one of the buttons the capture and draw buttons */
if (btnrect) {
if (btnrect)
{
TRACE("[%p] draw btn (%ld,%ld)-(%ld,%ld), Capture %s, style %08lx\n",
hwnd, btnrect->left, btnrect->top,
btnrect->right, btnrect->bottom,
(infoPtr->bCapture) ? "TRUE" : "FALSE",
dwStyle);
if (!infoPtr->bCapture)
PAGER_CaptureandTrack(infoPtr, hwnd);
{
TRACE("[%p] SetCapture\n", hwnd);
SetCapture(hwnd);
infoPtr->bCapture = TRUE;
}
if (dwStyle & PGS_AUTOSCROLL)
SetTimer(hwnd, TIMERID1, 0x3e, 0);
MapWindowPoints(0, hwnd, (LPPOINT)btnrect, 2);
hdc = GetWindowDC(hwnd);
/* OffsetRect(wnrect, 0 | 1, 0 | 1) */
PAGER_DrawButton(hdc, infoPtr->clrBk, *btnrect,
PAGER_IsHorizontal(hwnd), topLeft, btnstate);
ReleaseDC(hwnd, hdc);
return DefWindowProcW (hwnd, WM_MOUSEMOVE, wParam, lParam);
return 0;
}
}
/* If we think we are captured, then do release */
if (infoPtr->bCapture) {
infoPtr->bCapture = FALSE;
if (infoPtr->bCapture && (WindowFromPoint(pt) != hwnd))
{
NMHDR nmhdr;
if (GetCapture() == hwnd) {
ReleaseCapture();
/* Notify parent of released mouse capture */
{
NMHDR nmhdr;
ZeroMemory (&nmhdr, sizeof (NMHDR));
nmhdr.hwndFrom = hwnd;
nmhdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
nmhdr.code = NM_RELEASEDCAPTURE;
SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}
}
if (IsWindow(hwnd))
KillTimer(hwnd, TIMERID1);
infoPtr->bCapture = FALSE;
if (GetCapture() == hwnd)
{
ReleaseCapture();
if (infoPtr->TLbtnState == PGF_GRAYED)
{
infoPtr->TLbtnState = PGF_INVISIBLE;
SetWindowPos(hwnd, 0,0,0,0,0,
SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOZORDER | SWP_NOACTIVATE);
}
else if (infoPtr->TLbtnState == PGF_HOT)
{
infoPtr->TLbtnState = PGF_NORMAL;
/* FIXME: just invalidate button rect */
RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
}
if (infoPtr->BRbtnState == PGF_GRAYED)
{
infoPtr->BRbtnState = PGF_INVISIBLE;
SetWindowPos(hwnd, 0,0,0,0,0,
SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOZORDER | SWP_NOACTIVATE);
}
else if (infoPtr->BRbtnState == PGF_HOT)
{
infoPtr->BRbtnState = PGF_NORMAL;
/* FIXME: just invalidate button rect */
RedrawWindow(hwnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
}
/* Notify parent of released mouse capture */
memset(&nmhdr, 0, sizeof(NMHDR));
nmhdr.hwndFrom = hwnd;
nmhdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
nmhdr.code = NM_RELEASEDCAPTURE;
SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
(WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}
if (IsWindow(hwnd))
KillTimer(hwnd, TIMERID1);
}
return DefWindowProcW (hwnd, WM_MOUSEMOVE, wParam, lParam);
return 0;
}
static LRESULT
@ -1296,13 +1132,13 @@ PAGER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
hit = PAGER_HitTest(hwnd, &pt);
/* put btn in DEPRESSED state */
if (hit == HTLEFT || hit == HTTOP)
if (hit == PGB_TOPORLEFT)
{
repaintBtns = infoPtr->TLbtnState != PGF_DEPRESSED;
infoPtr->TLbtnState = PGF_DEPRESSED;
SetTimer(hwnd, TIMERID1, INITIAL_DELAY, 0);
}
else if (hit == HTRIGHT || hit == HTBOTTOM)
else if (hit == PGB_BOTTOMORRIGHT)
{
repaintBtns = infoPtr->BRbtnState != PGF_DEPRESSED;
infoPtr->BRbtnState = PGF_DEPRESSED;
@ -1314,21 +1150,29 @@ PAGER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
switch(hit)
{
case HTLEFT:
TRACE("[%p] PGF_SCROLLLEFT\n", hwnd);
PAGER_Scroll(hwnd, PGF_SCROLLLEFT);
case PGB_TOPORLEFT:
if (PAGER_IsHorizontal(hwnd))
{
TRACE("[%p] PGF_SCROLLLEFT\n", hwnd);
PAGER_Scroll(hwnd, PGF_SCROLLLEFT);
}
else
{
TRACE("[%p] PGF_SCROLLUP\n", hwnd);
PAGER_Scroll(hwnd, PGF_SCROLLUP);
}
break;
case HTTOP:
TRACE("[%p] PGF_SCROLLUP\n", hwnd);
PAGER_Scroll(hwnd, PGF_SCROLLUP);
break;
case HTRIGHT:
TRACE("[%p] PGF_SCROLLRIGHT\n", hwnd);
PAGER_Scroll(hwnd, PGF_SCROLLRIGHT);
break;
case HTBOTTOM:
TRACE("[%p] PGF_SCROLLDOWN\n", hwnd);
PAGER_Scroll(hwnd, PGF_SCROLLDOWN);
case PGB_BOTTOMORRIGHT:
if (PAGER_IsHorizontal(hwnd))
{
TRACE("[%p] PGF_SCROLLRIGHT\n", hwnd);
PAGER_Scroll(hwnd, PGF_SCROLLRIGHT);
}
else
{
TRACE("[%p] PGF_SCROLLDOWN\n", hwnd);
PAGER_Scroll(hwnd, PGF_SCROLLDOWN);
}
break;
default:
break;
@ -1347,25 +1191,14 @@ PAGER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
KillTimer (hwnd, TIMERID2);
/* make PRESSED btns NORMAL but don't hide gray btns */
PAGER_UpdateBtns(hwnd, infoPtr, -1, FALSE);
if (infoPtr->TLbtnState & (PGF_HOT | PGF_DEPRESSED))
infoPtr->TLbtnState = PGF_NORMAL;
if (infoPtr->BRbtnState & (PGF_HOT | PGF_DEPRESSED))
infoPtr->BRbtnState = PGF_NORMAL;
return 0;
}
static LRESULT
PAGER_NCLButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
POINT pt;
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
TRACE("[%p] at (%ld,%ld)\n", hwnd, pt.x, pt.y );
MapWindowPoints(0, hwnd, &pt, 1);
lParam = MAKELONG(pt.x, pt.y);
return PAGER_LButtonDown (hwnd, wParam, lParam);
}
static LRESULT
PAGER_Timer (HWND hwnd, WPARAM wParam)
{
@ -1375,14 +1208,12 @@ PAGER_Timer (HWND hwnd, WPARAM wParam)
/* if initial timer, kill it and start the repeat timer */
if (wParam == TIMERID1) {
if (PAGER_IsHorizontal(hwnd)) {
dir = (infoPtr->TLbtnState & PGF_DEPRESSED) ?
PGF_SCROLLLEFT : PGF_SCROLLRIGHT;
}
else {
dir = (infoPtr->TLbtnState & PGF_DEPRESSED) ?
PGF_SCROLLUP : PGF_SCROLLDOWN;
}
if (infoPtr->TLbtnState == PGF_HOT)
dir = PAGER_IsHorizontal(hwnd) ?
PGF_SCROLLLEFT : PGF_SCROLLUP;
else
dir = PAGER_IsHorizontal(hwnd) ?
PGF_SCROLLRIGHT : PGF_SCROLLDOWN;
TRACE("[%p] TIMERID1: style=%08lx, dir=%d\n", hwnd, dwStyle, dir);
KillTimer(hwnd, TIMERID1);
SetTimer(hwnd, TIMERID1, REPEAT_DELAY, 0);
@ -1412,15 +1243,6 @@ PAGER_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
HDC hdc = (HDC)wParam;
HWND parent;
/* native does:
* parent = GetParent(pager)
* pt.x=0; pt.y=0; ?????
* MapWindowPoints(pager, parent, &pt, 1)
* OffsetWindowOrgEx(hdc, pt.x, pt.y, &ptorg)
* SendMessageW(parent, WM_ERASEBKGND, hdc, 0)
* SetWindowOrgEx(hdc, 0, 0, 0)
*/
pt.x = 0;
pt.y = 0;
parent = GetParent(hwnd);
@ -1429,25 +1251,6 @@ PAGER_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
SendMessageW (parent, WM_ERASEBKGND, wParam, lParam);
SetWindowOrgEx (hdc, ptorig.x, ptorig.y, 0);
#if 0
PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
HBRUSH hBrush = CreateSolidBrush(infoPtr->clrBk);
RECT rect;
GetClientRect (hwnd, &rect);
FillRect ((HDC)wParam, &rect, hBrush);
/* background color of the child should be the same as the pager */
if (infoPtr->hwndChild)
{
GetClientRect (infoPtr->hwndChild, &rect);
FillRect ((HDC)wParam, &rect, hBrush);
}
DeleteObject (hBrush);
#endif
return TRUE;
}
@ -1541,40 +1344,22 @@ PAGER_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_NCHITTEST:
return PAGER_NCHitTest (hwnd, wParam, lParam);
case WM_SETCURSOR:
{
if (hwnd == (HWND)wParam)
return PAGER_SetCursor(hwnd, wParam, lParam);
else /* its for the child */
return 0;
}
case WM_MOUSEMOVE:
if (infoPtr->bForward && infoPtr->hwndChild)
PostMessageW(infoPtr->hwndChild, WM_MOUSEMOVE, wParam, lParam);
return PAGER_MouseMove (hwnd, wParam, lParam);
case WM_MOUSELEAVE:
return PAGER_MouseLeave (hwnd, wParam, lParam);
case WM_NCLBUTTONDOWN:
return PAGER_NCLButtonDown (hwnd, wParam, lParam);
case WM_LBUTTONDOWN:
return PAGER_LButtonDown (hwnd, wParam, lParam);
case WM_NCLBUTTONUP:
case WM_LBUTTONUP:
return PAGER_LButtonUp (hwnd, wParam, lParam);
case WM_ERASEBKGND:
return PAGER_EraseBackground (hwnd, wParam, lParam);
/*
case WM_PAINT:
return PAGER_Paint (hwnd, wParam);
*/
case WM_TIMER:
return PAGER_Timer (hwnd, wParam);
return PAGER_Timer (hwnd, wParam);
case WM_NOTIFY:
case WM_COMMAND:

View file

@ -34,13 +34,12 @@
* - Messages:
* o PSM_GETRESULT
* o PSM_IDTOINDEX
* o PSM_INDEXTOID
* o PSM_INDEXTOPAGE
* o PSM_INSERTPAGE
* o PSM_PAGETOINDEX
* o PSM_RECALCPAGESIZES
* o PSM_SETHEADERSUBTITLE
* o PSM_SETHEADERTITLE
* o WM_HELP
* o WM_CONTEXTMENU
* - Notifications:
* o PSN_GETOBJECT
* o PSN_QUERYINITIALFOCUS
@ -48,10 +47,8 @@
* - Styles:
* o PSH_WIZARDHASFINISH
* o PSH_RTLREADING
* o PSH_WIZARDCONTEXTHELP
* o PSH_STRETCHWATERMARK
* o PSH_USEPAGELANG
* o PSH_NOCONTEXTHELP
* o PSH_USEPSTARTPAGE
* - Page styles:
* o PSP_USEFUSIONCONTEXT
@ -237,18 +234,14 @@ static VOID PROPSHEET_UnImplementedFlags(DWORD dwFlags)
* unhandled header flags:
* PSH_WIZARDHASFINISH 0x00000010
* PSH_RTLREADING 0x00000800
* PSH_WIZARDCONTEXTHELP 0x00001000
* PSH_STRETCHWATERMARK 0x00040000
* PSH_USEPAGELANG 0x00200000
* PSH_NOCONTEXTHELP 0x02000000 also not in .h
*/
add_flag(PSH_WIZARDHASFINISH);
add_flag(PSH_RTLREADING);
add_flag(PSH_WIZARDCONTEXTHELP);
add_flag(PSH_STRETCHWATERMARK);
add_flag(PSH_USEPAGELANG);
add_flag(PSH_NOCONTEXTHELP);
if (string[0] != '\0')
FIXME("%s\n", string);
}
@ -689,9 +682,29 @@ int PROPSHEET_CreateDialog(PropSheetInfo* psInfo)
memcpy(temp, template, resSize);
if (psInfo->ppshheader.dwFlags & PSH_NOCONTEXTHELP)
{
if (((MyDLGTEMPLATEEX*)temp)->signature == 0xFFFF)
((MyDLGTEMPLATEEX*)temp)->style &= ~DS_CONTEXTHELP;
else
((DLGTEMPLATE*)temp)->style &= ~DS_CONTEXTHELP;
}
if ((psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD) &&
(psInfo->ppshheader.dwFlags & PSH_WIZARDCONTEXTHELP))
{
if (((MyDLGTEMPLATEEX*)temp)->signature == 0xFFFF)
((MyDLGTEMPLATEEX*)temp)->style |= DS_CONTEXTHELP;
else
((DLGTEMPLATE*)temp)->style |= DS_CONTEXTHELP;
}
if (psInfo->useCallback)
(*(psInfo->ppshheader.pfnCallback))(0, PSCB_PRECREATE, (LPARAM)temp);
/* NOTE: MSDN states "Returns a positive value if successful, or -1
* otherwise for modal property sheets.", but this is wrong. The
* actual return value is either TRUE (success), FALSE (cancel) or
* -1 (error). */
if( psInfo->unicode )
{
if (!(psInfo->ppshheader.dwFlags & PSH_MODELESS))
@ -2568,7 +2581,16 @@ static LRESULT PROPSHEET_IndexToHwnd(HWND hwndDlg, int iPageIndex)
*/
static LRESULT PROPSHEET_PageToIndex(HWND hwndDlg, HPROPSHEETPAGE hPage)
{
FIXME("(%p, %p): stub\n", hwndDlg, hPage);
int index;
PropSheetInfo * psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
PropSheetInfoStr);
TRACE("(%p, %p)\n", hwndDlg, hPage);
for (index = 0; index < psInfo->nPages; index++)
if (psInfo->proppage[index].hpage == hPage)
return index;
WARN("%p not found\n", hPage);
return -1;
}
@ -2577,8 +2599,14 @@ static LRESULT PROPSHEET_PageToIndex(HWND hwndDlg, HPROPSHEETPAGE hPage)
*/
static LRESULT PROPSHEET_IndexToPage(HWND hwndDlg, int iPageIndex)
{
FIXME("(%p, %d): stub\n", hwndDlg, iPageIndex);
return 0;
PropSheetInfo * psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
PropSheetInfoStr);
TRACE("(%p, %d)\n", hwndDlg, iPageIndex);
if (iPageIndex<0 || iPageIndex>=psInfo->nPages) {
WARN("%d out of range.\n", iPageIndex);
return 0;
}
return (LRESULT)psInfo->proppage[iPageIndex].hpage;
}
/******************************************************************************
@ -2595,8 +2623,19 @@ static LRESULT PROPSHEET_IdToIndex(HWND hwndDlg, int iPageId)
*/
static LRESULT PROPSHEET_IndexToId(HWND hwndDlg, int iPageIndex)
{
FIXME("(%p, %d): stub\n", hwndDlg, iPageIndex);
return 0;
PropSheetInfo * psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
PropSheetInfoStr);
LPCPROPSHEETPAGEW psp;
TRACE("(%p, %d)\n", hwndDlg, iPageIndex);
if (iPageIndex<0 || iPageIndex>=psInfo->nPages) {
WARN("%d out of range.\n", iPageIndex);
return 0;
}
psp = (LPCPROPSHEETPAGEW)psInfo->proppage[iPageIndex].hpage;
if (psp->dwFlags & PSP_DLGINDIRECT || HIWORD(psp->u.pszTemplate)) {
return 0;
}
return (LRESULT)psp->u.pszTemplate;
}
/******************************************************************************
@ -3374,6 +3413,9 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwnd, PropSheetInfoStr);
if (!psInfo)
return FALSE;
/* No default handler, forward notification to active page */
if (psInfo->activeValid && psInfo->active_page != -1)
{
@ -3409,6 +3451,9 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
PropSheetInfoStr);
HWND hwndPage = 0;
if (!psInfo)
return FALSE;
if (psInfo->activeValid && psInfo->active_page != -1)
hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
@ -3470,6 +3515,9 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwnd,
PropSheetInfoStr);
if (!psInfo)
return FALSE;
psInfo->restartWindows = TRUE;
return TRUE;
}
@ -3479,6 +3527,9 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwnd,
PropSheetInfoStr);
if (!psInfo)
return FALSE;
psInfo->rebootSystem = TRUE;
return TRUE;
}

View file

@ -1,3 +1,74 @@
/*
* Rebar control
*
* Copyright 1998, 1999 Eric Kohl
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Mar. 14, 2004, by Robert Shearman.
*
* 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:
* - RBS_DBLCLKTOGGLE
* - RBS_FIXEDORDER
* - RBS_REGISTERDROP
* - RBS_TOOLTIPS
* - CCS_NORESIZE
* - CCS_NOMOVEX
* - CCS_NOMOVEY
* Messages:
* - RB_BEGINDRAG
* - RB_DRAGMOVE
* - RB_ENDDRAG
* - RB_GETBANDMARGINS
* - RB_GETCOLORSCHEME
* - RB_GETDROPTARGET
* - RB_GETPALETTE
* - RB_SETCOLORSCHEME
* - RB_SETPALETTE
* - RB_SETTOOLTIPS
* - WM_CHARTOITEM
* - WM_LBUTTONDBLCLK
* - WM_MEASUREITEM
* - WM_PALETTECHANGED
* - WM_PRINTCLIENT
* - WM_QUERYNEWPALETTE
* - WM_RBUTTONDOWN
* - WM_RBUTTONUP
* - WM_SYSCOLORCHANGE
* - WM_VKEYTOITEM
* - WM_WININICHANGE
* Notifications:
* - NM_HCHITTEST
* - NM_RELEASEDCAPTURE
* - RBN_AUTOBREAK
* - RBN_GETOBJECT
* - RBN_MINMAX
* Band styles:
* - RBBS_FIXEDBMP
* Native uses (on each draw!!) SM_CYBORDER (or SM_CXBORDER for CCS_VERT)
* to set the size of the separator width (the value SEP_WIDTH_SIZE
* in here). Should be fixed!!
*/
/*
* Testing: set to 1 to make background brush *always* green
*/
@ -18,127 +89,6 @@
* at least RB_INSERTBAND
*/
/*
* Rebar control rev 8e
*
* Copyright 1998, 1999 Eric Kohl
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* 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
* An author is needed! Any volunteers?
* I will only improve this control once in a while.
* Eric <ekohl@abo.rhein-zeitung.de>
*
* TODO:
* - vertical placement
* - ComboBox and ComboBoxEx placement
* - center image
* - Layout code.
* - Display code.
* - Some messages.
* - All notifications.
* Changes Guy Albertelli <galberte@neo.lrun.com>
* rev 2,3,4
* - Implement initial version of row grouping, row separators,
* text and background colors. Support additional messages.
* Support RBBS_BREAK. Implement ERASEBKGND and improve painting.
* rev 5
* - implement support for dragging Gripper left or right in a row. Supports
* WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_MOUSEMOVE. Also support
* RBS_BANDBORDERS.
* rev 6
* - Fix or implement notifications for RBN_HEIGHTCHANGE, RBN_CHILDSIZE.
* - Correct styles RBBS_NOGRIPPER, RBBS_GRIPPERALWAYS, and RBBS_FIXEDSIZE.
* - Fix algorithm for Layout and AdjustBand.
*
* rev 7
* - Fix algorithm for _Layout and _AdjustBand.
* - Fix or implement RBN_ENDDRAG, RB_MOVEBAND, WM_SETREDRAW,
* WM_STYLECHANGED, RB_MINIMIZEBAND, RBBS_VARIABLEHEIGHT, RBS_VARHEIGHT,
* RBBS_HIDDEN, WM_NOTIFYFORMAT, NM_NCHITTEST, WM_SETREDRAW, RBS_AUTOSIZE,
* WM_SETFONT, RBS_BORDERS
* - Create structures in WM_NCCREATE
* - Additional performance enhancements.
*
* rev 8
* 1. Create array of start and end band indexes by row and use.
* 2. Fix problem with REBAR_Layout Phase 2b to process only if only
* band in row.
* 3. Set the Caption Font (Regular) as default font for text.
* 4. Delete font handle on control distruction.
* 5. Add UpdateWindow call in _MoveChildWindows to match repainting done
* by native control
* 6. Improve some traces.
* 7. Invalidate window rectangles after SetBandInfo, InsertBand, ShowBand
* so that repainting is correct.
* 8. Implement RB_MAXIMIZEBAND for the "ideal=TRUE" case.
* 9. Implement item custom draw notifications partially. Only done for
* ITEMPREPAINT and ITEMPOSTPAINT. (Used by IE4 for "Favorites" frame
* to draw the word "Favorites").
* rev 8a
* 10. Handle CCS_NODIVIDER and fix WS_BORDER code.
* 11. Fix logic error in _AdjustBands where flag was set to valid band
* number (0) to indicate *no* band.
* 12. Fix CCS_VERT errors in _ForceResize, _NCCalcSize, and _NCPaint.
* 13. Support some special cases of CCS_TOP (and therefore CCS_LEFT),
* CCS_BOTTOM (and therefore CCS_RIGHT) and CCS_NOPARENTALIGN. Not
* at all sure whether this is all cases.
* 14. Handle returned value for the RBN_CHILDSIZE notify.
* 15. Implement RBBS_CHILDEDGE, and set each bands "offChild" at _Layout
* time.
* 16. Fix REBARSPACE. It should depend on CCS_NODIVIDER.
* rev 8b
* 17. Fix determination of whether Gripper is needed in _ValidateBand.
* 18. Fix _AdjustBand processing of RBBS_FIXEDSIZE.
* rev 8c
* 19. Fix problem in _Layout when all lengths are 0.
* 20. If CLR_NONE specified, we will use default BtnFace color when drawing.
* 21. Fix test in REBAR_Layout.
* rev 8d
* 22. Add support for WM_WINDOWPOSCHANGED to save new origin of window.
* 23. Correct RBN_CHILDSIZE rect value for CCS_VERT rebar.
* 24. Do UpdateWindow only if doing redraws.
* rev 8e
* 25. Adjust setting of offChild.cx based on RBBS_CHILDEDGE.
*
*
* Still to do:
* 2. Following still not handled: RBBS_FIXEDBMP,
* CCS_NORESIZE,
* CCS_NOMOVEX, CCS_NOMOVEY
* 3. Following are only partially handled:
* RBS_AUTOSIZE, RBBS_VARIABLEHEIGHT
* 5. Native uses (on each draw!!) SM_CYBORDER (or SM_CXBORDER for CCS_VERT)
* to set the size of the separator width (the value SEP_WIDTH_SIZE
* in here). Should be fixed!!
* 6. The following messages are not implemented:
* RB_BEGINDRAG, RB_DRAGMOVE, RB_ENDDRAG, RB_GETCOLORSCHEME,
* RB_GETDROPTARGET, RB_MAXIMIZEBAND,
* RB_SETCOLORSCHEME, RB_SETPALETTE, RB_SETTOOLTIPS
* WM_CHARTOITEM, WM_LBUTTONDBLCLK, WM_MEASUREITEM,
* WM_PALETTECHANGED, WM_PRINTCLIENT, WM_QUERYNEWPALETTE,
* WM_RBUTTONDOWN, WM_RBUTTONUP,
* WM_SYSCOLORCHANGE, WM_VKEYTOITEM, WM_WININICHANGE
* 7. The following notifications are not implemented:
* NM_CUSTOMDRAW, NM_RELEASEDCAPTURE
* RBN_MINMAX
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@ -3131,9 +3081,9 @@ REBAR_InsertBandA (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
}
/* post copy */
if (uIndex < infoPtr->uNumBands - 1) {
if (uIndex < infoPtr->uNumBands) {
memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
(infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
(infoPtr->uNumBands - uIndex) * sizeof(REBAR_BAND));
}
Free (oldBands);

View file

@ -131,6 +131,16 @@ static BOOL COMCTL32_ChrCmpW(WCHAR ch1, WCHAR ch2)
return COMCTL32_ChrCmpHelperW(ch1, ch2, 0);
}
/*************************************************************************
* COMCTL32_ChrCmpIW
*
* Internal helper function.
*/
static BOOL COMCTL32_ChrCmpIW(WCHAR ch1, WCHAR ch2)
{
return COMCTL32_ChrCmpHelperW(ch1, ch2, NORM_IGNORECASE);
}
/**************************************************************************
* StrChrA [COMCTL32.350]
*
@ -627,7 +637,7 @@ LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch)
while (lpszStr <= lpszEnd && *lpszStr)
{
if (!COMCTL32_ChrCmpIA(*lpszSearch, *lpszStr))
if (!COMCTL32_ChrCmpIW(*lpszSearch, *lpszStr))
{
if (!StrCmpNIW(lpszStr, lpszSearch, iLen))
lpszRet = (LPWSTR)lpszStr;

View file

@ -113,6 +113,9 @@ typedef struct
#define DEFAULT_TAB_WIDTH 96
#define TAB_GetInfoPtr(hwnd) ((TAB_INFO *)GetWindowLongPtrW(hwnd,0))
/* Since items are variable sized, cannot directly access them */
#define TAB_GetItem(info,i) \
((TAB_ITEM*)((LPBYTE)info->items + (i) * TAB_ITEM_SIZE(info)))
/******************************************************************************
* Hot-tracking timer constants
@ -189,7 +192,7 @@ TAB_DumpItemInternal(TAB_INFO *infoPtr, UINT iItem)
if (TRACE_ON(tab)) {
TAB_ITEM *ti;
ti = &infoPtr->items[iItem];
ti = TAB_GetItem(infoPtr, iItem);
TRACE("tab %d, mask=0x%08x, dwState=0x%08lx, pszText=%s, iImage=%d\n",
iItem, ti->mask, ti->dwState, debugstr_w(ti->pszText),
ti->iImage);
@ -323,7 +326,7 @@ static BOOL TAB_InternalGetItemRect(
itemRect = &tmpItemRect;
/* Retrieve the unmodified item rect. */
*itemRect = infoPtr->items[itemIndex].rect;
*itemRect = TAB_GetItem(infoPtr,itemIndex)->rect;
/* calculate the times bottom and top based on the row */
GetClientRect(hwnd, &clientRect);
@ -361,7 +364,7 @@ static BOOL TAB_InternalGetItemRect(
{
OffsetRect(itemRect,
0,
-infoPtr->items[infoPtr->leftmostVisible].rect.top);
-TAB_GetItem(infoPtr, infoPtr->leftmostVisible)->rect.top);
/*
* Move the rectangle so the first item is slightly offset from
@ -374,7 +377,7 @@ static BOOL TAB_InternalGetItemRect(
} else
{
OffsetRect(itemRect,
-infoPtr->items[infoPtr->leftmostVisible].rect.left,
-TAB_GetItem(infoPtr, infoPtr->leftmostVisible)->rect.left,
0);
/*
@ -1014,11 +1017,11 @@ static void TAB_SetupScrolling(
{
vsize = clientRect->right - (controlPos.right - controlPos.left + 1);
maxRange = infoPtr->uNumItem;
tabwidth = infoPtr->items[maxRange - 1].rect.right;
tabwidth = TAB_GetItem(infoPtr, infoPtr->uNumItem - 1)->rect.right;
for(; maxRange > 0; maxRange--)
{
if(tabwidth - infoPtr->items[maxRange - 1].rect.left > vsize)
if(tabwidth - TAB_GetItem(infoPtr,maxRange - 1)->rect.left > vsize)
break;
}
@ -1142,12 +1145,14 @@ static void TAB_SetItemBounds (HWND hwnd)
for (curItem = 0; curItem < infoPtr->uNumItem; curItem++)
{
TAB_ITEM *curr = TAB_GetItem(infoPtr, curItem);
/* Set the leftmost position of the tab. */
infoPtr->items[curItem].rect.left = curItemLeftPos;
curr->rect.left = curItemLeftPos;
if ((lStyle & TCS_FIXEDWIDTH) || !infoPtr->items[curItem].pszText)
if ((lStyle & TCS_FIXEDWIDTH) || !curr->pszText)
{
infoPtr->items[curItem].rect.right = infoPtr->items[curItem].rect.left +
curr->rect.right = curr->rect.left +
max(infoPtr->tabWidth, icon_width);
}
else
@ -1155,17 +1160,13 @@ static void TAB_SetItemBounds (HWND hwnd)
int num = 2;
/* Calculate how wide the tab is depending on the text it contains */
GetTextExtentPoint32W(hdc, infoPtr->items[curItem].pszText,
lstrlenW(infoPtr->items[curItem].pszText), &size);
GetTextExtentPoint32W(hdc, curr->pszText,
lstrlenW(curr->pszText), &size);
infoPtr->items[curItem].rect.right = infoPtr->items[curItem].rect.left +
size.cx + icon_width +
num * infoPtr->uHItemPadding;
curr->rect.right = curr->rect.left + size.cx + icon_width +
num * infoPtr->uHItemPadding;
TRACE("for <%s>, l,r=%ld,%ld, num=%d\n",
debugstr_w(infoPtr->items[curItem].pszText),
infoPtr->items[curItem].rect.left,
infoPtr->items[curItem].rect.right,
num);
debugstr_w(curr->pszText), curr->rect.left, curr->rect.right, num);
}
/*
@ -1177,29 +1178,23 @@ static void TAB_SetItemBounds (HWND hwnd)
*/
if (((lStyle & TCS_MULTILINE) || (lStyle & TCS_VERTICAL)) &&
(infoPtr->items[curItem].rect.right >
(curr->rect.right >
(clientRect.right - CONTROL_BORDER_SIZEX - DISPLAY_AREA_PADDINGX)))
{
infoPtr->items[curItem].rect.right -=
infoPtr->items[curItem].rect.left;
curr->rect.right -= curr->rect.left;
infoPtr->items[curItem].rect.left = 0;
curr->rect.left = 0;
curItemRowCount++;
TRACE("wrapping <%s>, l,r=%ld,%ld\n",
debugstr_w(infoPtr->items[curItem].pszText),
infoPtr->items[curItem].rect.left,
infoPtr->items[curItem].rect.right);
TRACE("wrapping <%s>, l,r=%ld,%ld\n", debugstr_w(curr->pszText),
curr->rect.left, curr->rect.right);
}
infoPtr->items[curItem].rect.bottom = 0;
infoPtr->items[curItem].rect.top = curItemRowCount - 1;
curr->rect.bottom = 0;
curr->rect.top = curItemRowCount - 1;
TRACE("TextSize: %li\n", size.cx);
TRACE("Rect: T %li, L %li, B %li, R %li\n",
infoPtr->items[curItem].rect.top,
infoPtr->items[curItem].rect.left,
infoPtr->items[curItem].rect.bottom,
infoPtr->items[curItem].rect.right);
TRACE("Rect: T %li, L %li, B %li, R %li\n", curr->rect.top,
curr->rect.left, curr->rect.bottom, curr->rect.right);
/*
* The leftmost position of the next item is the rightmost position
@ -1207,12 +1202,12 @@ static void TAB_SetItemBounds (HWND hwnd)
*/
if (lStyle & TCS_BUTTONS)
{
curItemLeftPos = infoPtr->items[curItem].rect.right + BUTTON_SPACINGX;
curItemLeftPos = curr->rect.right + BUTTON_SPACINGX;
if (lStyle & TCS_FLATBUTTONS)
curItemLeftPos += FLAT_BTN_SPACINGX;
}
else
curItemLeftPos = infoPtr->items[curItem].rect.right;
curItemLeftPos = curr->rect.right;
}
if (!((lStyle & TCS_MULTILINE) || (lStyle & TCS_VERTICAL)))
@ -1260,15 +1255,14 @@ static void TAB_SetItemBounds (HWND hwnd)
iItm++,iCount++)
{
/* normalize the current rect */
TAB_ITEM *curr = TAB_GetItem(infoPtr, iItm);
/* shift the item to the left side of the clientRect */
infoPtr->items[iItm].rect.right -=
infoPtr->items[iItm].rect.left;
infoPtr->items[iItm].rect.left = 0;
curr->rect.right -= curr->rect.left;
curr->rect.left = 0;
TRACE("r=%ld, cl=%d, cl.r=%ld, iCount=%d, iRow=%d, uNumRows=%d, remTab=%d, tabPerRow=%d\n",
infoPtr->items[iItm].rect.right,
curItemLeftPos, clientRect.right,
curr->rect.right, curItemLeftPos, clientRect.right,
iCount, iRow, infoPtr->uNumRows, remTab, tabPerRow);
/* if we have reached the maximum number of tabs on this row */
@ -1292,23 +1286,21 @@ static void TAB_SetItemBounds (HWND hwnd)
}
/* shift the item to the right to place it as the next item in this row */
infoPtr->items[iItm].rect.left += curItemLeftPos;
infoPtr->items[iItm].rect.right += curItemLeftPos;
infoPtr->items[iItm].rect.top = iRow;
curr->rect.left += curItemLeftPos;
curr->rect.right += curItemLeftPos;
curr->rect.top = iRow;
if (lStyle & TCS_BUTTONS)
{
curItemLeftPos = infoPtr->items[iItm].rect.right + 1;
curItemLeftPos = curr->rect.right + 1;
if (lStyle & TCS_FLATBUTTONS)
curItemLeftPos += FLAT_BTN_SPACINGX;
}
else
curItemLeftPos = infoPtr->items[iItm].rect.right;
curItemLeftPos = curr->rect.right;
TRACE("arranging <%s>, l,r=%ld,%ld, row=%ld\n",
debugstr_w(infoPtr->items[iItm].pszText),
infoPtr->items[iItm].rect.left,
infoPtr->items[iItm].rect.right,
infoPtr->items[iItm].rect.top);
debugstr_w(curr->pszText), curr->rect.left,
curr->rect.right, curr->rect.top);
}
/*
@ -1321,14 +1313,16 @@ static void TAB_SetItemBounds (HWND hwnd)
while(iIndexStart < infoPtr->uNumItem)
{
TAB_ITEM *start = TAB_GetItem(infoPtr, iIndexStart);
/*
* find the indexs of the row
* find the index of the row
*/
/* find the first item on the next row */
for (iIndexEnd=iIndexStart;
(iIndexEnd < infoPtr->uNumItem) &&
(infoPtr->items[iIndexEnd].rect.top ==
infoPtr->items[iIndexStart].rect.top) ;
(TAB_GetItem(infoPtr, iIndexEnd)->rect.top ==
start->rect.top) ;
iIndexEnd++)
/* intentionally blank */;
@ -1339,7 +1333,7 @@ static void TAB_SetItemBounds (HWND hwnd)
*/
/* find the amount of space remaining on this row */
widthDiff = clientRect.right - (2 * SELECTED_TAB_OFFSET) -
infoPtr->items[iIndexEnd - 1].rect.right;
TAB_GetItem(infoPtr, iIndexEnd - 1)->rect.right;
/* iCount is the number of tab items on this row */
iCount = iIndexEnd - iIndexStart;
@ -1351,26 +1345,26 @@ static void TAB_SetItemBounds (HWND hwnd)
/* add widthDiff/iCount, or extra space/items on row, to each item on this row */
for (iIndex=iIndexStart, iCount=0; iIndex < iIndexEnd; iIndex++, iCount++)
{
infoPtr->items[iIndex].rect.left += iCount * widthDiff;
infoPtr->items[iIndex].rect.right += (iCount + 1) * widthDiff;
TAB_ITEM *item = TAB_GetItem(infoPtr, iIndex);
item->rect.left += iCount * widthDiff;
item->rect.right += (iCount + 1) * widthDiff;
TRACE("adjusting 1 <%s>, l,r=%ld,%ld\n",
debugstr_w(infoPtr->items[iIndex].pszText),
infoPtr->items[iIndex].rect.left,
infoPtr->items[iIndex].rect.right);
debugstr_w(item->pszText),
item->rect.left, item->rect.right);
}
infoPtr->items[iIndex - 1].rect.right += remainder;
TAB_GetItem(infoPtr, iIndex - 1)->rect.right += remainder;
}
else /* we have only one item on this row, make it take up the entire row */
{
infoPtr->items[iIndexStart].rect.left = clientRect.left;
infoPtr->items[iIndexStart].rect.right = clientRect.right - 4;
start->rect.left = clientRect.left;
start->rect.right = clientRect.right - 4;
TRACE("adjusting 2 <%s>, l,r=%ld,%ld\n",
debugstr_w(infoPtr->items[iIndexStart].pszText),
infoPtr->items[iIndexStart].rect.left,
infoPtr->items[iIndexStart].rect.right);
debugstr_w(start->pszText),
start->rect.left, start->rect.right);
}
@ -1386,7 +1380,7 @@ static void TAB_SetItemBounds (HWND hwnd)
RECT rcOriginal;
for(iIndex = 0; iIndex < infoPtr->uNumItem; iIndex++)
{
rcItem = &(infoPtr->items[iIndex].rect);
rcItem = &TAB_GetItem(infoPtr, iIndex)->rect;
rcOriginal = *rcItem;
@ -1584,7 +1578,7 @@ TAB_DrawItemInterior
}
else
{
drawRect->bottom -= (infoPtr->items[iItem].rect.top != infoPtr->uNumRows-1)? 2:2;
drawRect->bottom -= 2;
InflateRect(drawRect, -2, 0);
}
}
@ -1626,7 +1620,7 @@ TAB_DrawItemInterior
*/
oldBkMode = SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, (((iItem == infoPtr->iHotTracked) && !(lStyle & TCS_FLATBUTTONS)) |
(infoPtr->items[iItem].dwState & TCIS_HIGHLIGHTED)) ?
(TAB_GetItem(infoPtr, iItem)->dwState & TCIS_HIGHLIGHTED)) ?
comctl32_color.clrHighlight : comctl32_color.clrBtnText);
/*
@ -1666,7 +1660,7 @@ TAB_DrawItemInterior
dis.hDC = hdc;
CopyRect(&dis.rcItem,drawRect);
dis.itemData = 0;
memcpy( &dis.itemData, infoPtr->items[iItem].extra, min(sizeof(dis.itemData),infoPtr->cbInfo) );
memcpy( &dis.itemData, TAB_GetItem(infoPtr, iItem)->extra, min(sizeof(dis.itemData),infoPtr->cbInfo) );
/*
* send the draw message
@ -1675,6 +1669,7 @@ TAB_DrawItemInterior
}
else
{
TAB_ITEM *item = TAB_GetItem(infoPtr, iItem);
RECT rcTemp;
RECT rcImage;
@ -1690,17 +1685,16 @@ TAB_DrawItemInterior
rcText.left = rcText.top = rcText.right = rcText.bottom = 0;
/* get the rectangle that the text fits in */
if (infoPtr->items[iItem].pszText)
if (item->pszText)
{
DrawTextW(hdc, infoPtr->items[iItem].pszText, -1,
&rcText, DT_CALCRECT);
DrawTextW(hdc, item->pszText, -1, &rcText, DT_CALCRECT);
}
/*
* If not owner draw, then do the drawing ourselves.
*
* Draw the icon.
*/
if (infoPtr->himl && (infoPtr->items[iItem].mask & TCIF_IMAGE))
if (infoPtr->himl && (item->mask & TCIF_IMAGE))
{
INT cx;
INT cy;
@ -1728,7 +1722,7 @@ TAB_DrawItemInterior
center_offset_v = 0;
TRACE("for <%s>, c_o_h=%d, c_o_v=%d, draw=(%ld,%ld)-(%ld,%ld), textlen=%ld\n",
debugstr_w(infoPtr->items[iItem].pszText), center_offset_h, center_offset_v,
debugstr_w(item->pszText), center_offset_h, center_offset_v,
drawRect->left, drawRect->top, drawRect->right, drawRect->bottom,
(rcText.right-rcText.left));
@ -1755,11 +1749,11 @@ TAB_DrawItemInterior
}
TRACE("drawing image=%d, left=%ld, top=%ld\n",
infoPtr->items[iItem].iImage, rcImage.left, rcImage.top-1);
item->iImage, rcImage.left, rcImage.top-1);
ImageList_Draw
(
infoPtr->himl,
infoPtr->items[iItem].iImage,
item->iImage,
hdc,
rcImage.left,
rcImage.top,
@ -1835,15 +1829,15 @@ TAB_DrawItemInterior
hFont = CreateFontIndirectA(&logfont);
SelectObject(hdc, hFont);
if (infoPtr->items[iItem].pszText)
if (item->pszText)
{
ExtTextOutW(hdc,
(lStyle & TCS_BOTTOM) ? drawRect->right : drawRect->left,
(!(lStyle & TCS_BOTTOM)) ? drawRect->bottom : drawRect->top,
ETO_CLIPPED,
drawRect,
infoPtr->items[iItem].pszText,
lstrlenW(infoPtr->items[iItem].pszText),
item->pszText,
lstrlenW(item->pszText),
0);
}
@ -1852,16 +1846,16 @@ TAB_DrawItemInterior
else
{
TRACE("for <%s>, c_o_h=%d, c_o_v=%d, draw=(%ld,%ld)-(%ld,%ld), textlen=%ld\n",
debugstr_w(infoPtr->items[iItem].pszText), center_offset_h, center_offset_v,
debugstr_w(item->pszText), center_offset_h, center_offset_v,
drawRect->left, drawRect->top, drawRect->right, drawRect->bottom,
(rcText.right-rcText.left));
if (infoPtr->items[iItem].pszText)
if (item->pszText)
{
DrawTextW
(
hdc,
infoPtr->items[iItem].pszText,
lstrlenW(infoPtr->items[iItem].pszText),
item->pszText,
lstrlenW(item->pszText),
drawRect,
DT_LEFT | DT_SINGLELINE
);
@ -2086,7 +2080,7 @@ static void TAB_DrawItem(
if (lStyle & TCS_BOTTOM)
{
/* Adjust both rectangles for topmost row */
if (infoPtr->items[iItem].rect.top == infoPtr->uNumRows-1)
if (TAB_GetItem(infoPtr, iItem)->rect.top == infoPtr->uNumRows-1)
{
fillRect.top -= 2;
r.top -= 1;
@ -2140,7 +2134,7 @@ static void TAB_DrawItem(
else
{
/* Adjust both rectangles for bottommost row */
if (infoPtr->items[iItem].rect.top == infoPtr->uNumRows-1)
if (TAB_GetItem(infoPtr, iItem)->rect.top == infoPtr->uNumRows-1)
{
fillRect.bottom += 3;
r.bottom += 2;
@ -2304,13 +2298,14 @@ static void TAB_EnsureSelectionVisible(
* style */
if ((infoPtr->uNumRows > 1) && !(lStyle & TCS_BUTTONS))
{
TAB_ITEM *selected = TAB_GetItem(infoPtr, iSelected);
INT newselected;
INT iTargetRow;
if(lStyle & TCS_VERTICAL)
newselected = infoPtr->items[iSelected].rect.left;
newselected = selected->rect.left;
else
newselected = infoPtr->items[iSelected].rect.top;
newselected = selected->rect.top;
/* the target row is always (number of rows - 1)
as row 0 is furthest from the clientRect */
@ -2324,12 +2319,14 @@ static void TAB_EnsureSelectionVisible(
for (i=0; i < infoPtr->uNumItem; i++)
{
/* move everything in the row of the selected item to the iTargetRow */
if (infoPtr->items[i].rect.left == newselected )
infoPtr->items[i].rect.left = iTargetRow;
TAB_ITEM *item = TAB_GetItem(infoPtr, i);
if (item->rect.left == newselected )
item->rect.left = iTargetRow;
else
{
if (infoPtr->items[i].rect.left > newselected)
infoPtr->items[i].rect.left-=1;
if (item->rect.left > newselected)
item->rect.left-=1;
}
}
}
@ -2337,12 +2334,14 @@ static void TAB_EnsureSelectionVisible(
{
for (i=0; i < infoPtr->uNumItem; i++)
{
if (infoPtr->items[i].rect.top == newselected )
infoPtr->items[i].rect.top = iTargetRow;
TAB_ITEM *item = TAB_GetItem(infoPtr, i);
if (item->rect.top == newselected )
item->rect.top = iTargetRow;
else
{
if (infoPtr->items[i].rect.top > newselected)
infoPtr->items[i].rect.top-=1;
if (item->rect.top > newselected)
item->rect.top-=1;
}
}
}
@ -2363,6 +2362,7 @@ static void TAB_EnsureSelectionVisible(
}
else
{
TAB_ITEM *selected = TAB_GetItem(infoPtr, iSelected);
RECT r;
INT width;
UINT i;
@ -2374,8 +2374,8 @@ static void TAB_EnsureSelectionVisible(
GetClientRect(infoPtr->hwndUpDown, &r);
width -= r.right;
if ((infoPtr->items[iSelected].rect.right -
infoPtr->items[iSelected].rect.left) >= width )
if ((selected->rect.right -
selected->rect.left) >= width )
{
/* Special case: width of selected item is greater than visible
* part of control.
@ -2386,8 +2386,7 @@ static void TAB_EnsureSelectionVisible(
{
for (i = infoPtr->leftmostVisible; i < infoPtr->uNumItem; i++)
{
if ((infoPtr->items[iSelected].rect.right -
infoPtr->items[i].rect.left) < width)
if ((selected->rect.right - TAB_GetItem(infoPtr, i)->rect.left) < width)
break;
}
infoPtr->leftmostVisible = i;
@ -2493,9 +2492,10 @@ TAB_Paint (HWND hwnd, WPARAM wParam)
}
static LRESULT
TAB_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
TAB_InsertItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
{
TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
TAB_ITEM *item;
TCITEMA *pti;
INT iItem;
RECT rect;
@ -2511,7 +2511,10 @@ TAB_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (iItem > infoPtr->uNumItem)
iItem = infoPtr->uNumItem;
TAB_DumpItemExternalA(pti, iItem);
if (bUnicode)
TAB_DumpItemExternalW((TCITEMW*)pti, iItem);
else
TAB_DumpItemExternalA(pti, iItem);
if (infoPtr->uNumItem == 0) {
@ -2520,20 +2523,21 @@ TAB_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
infoPtr->iSelected = 0;
}
else {
TAB_ITEM *oldItems = infoPtr->items;
LPBYTE oldItems = (LPBYTE)infoPtr->items;
infoPtr->uNumItem++;
infoPtr->items = Alloc (TAB_ITEM_SIZE(infoPtr) * infoPtr->uNumItem);
/* pre insert copy */
if (iItem > 0) {
memcpy (&infoPtr->items[0], &oldItems[0],
memcpy (infoPtr->items, oldItems,
iItem * TAB_ITEM_SIZE(infoPtr));
}
/* post insert copy */
if (iItem < infoPtr->uNumItem - 1) {
memcpy (&infoPtr->items[iItem+1], &oldItems[iItem],
memcpy (TAB_GetItem(infoPtr, iItem + 1),
oldItems + iItem * TAB_ITEM_SIZE(infoPtr),
(infoPtr->uNumItem - iItem - 1) * TAB_ITEM_SIZE(infoPtr));
}
@ -2544,17 +2548,28 @@ TAB_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
Free (oldItems);
}
infoPtr->items[iItem].mask = pti->mask;
item = TAB_GetItem(infoPtr, iItem);
item->mask = pti->mask;
item->pszText = NULL;
if (pti->mask & TCIF_TEXT)
Str_SetPtrAtoW (&infoPtr->items[iItem].pszText, pti->pszText);
{
if (bUnicode)
Str_SetPtrW (&item->pszText, (WCHAR*)pti->pszText);
else
Str_SetPtrAtoW (&item->pszText, pti->pszText);
}
if (pti->mask & TCIF_IMAGE)
infoPtr->items[iItem].iImage = pti->iImage;
item->iImage = pti->iImage;
else
item->iImage = -1;
if (pti->mask & TCIF_PARAM)
memcpy(infoPtr->items[iItem].extra, &pti->lParam, infoPtr->cbInfo);
memcpy(item->extra, &pti->lParam, infoPtr->cbInfo);
else
memset(infoPtr->items[iItem].extra, 0, infoPtr->cbInfo);
memset(item->extra, 0, infoPtr->cbInfo);
TAB_SetItemBounds(hwnd);
if (infoPtr->uNumItem > 1)
@ -2563,88 +2578,11 @@ TAB_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
InvalidateRect(hwnd, NULL, TRUE);
TRACE("[%p]: added item %d %s\n",
hwnd, iItem, debugstr_w(infoPtr->items[iItem].pszText));
hwnd, iItem, debugstr_w(item->pszText));
return iItem;
}
static LRESULT
TAB_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
TCITEMW *pti;
INT iItem;
RECT rect;
GetClientRect (hwnd, &rect);
TRACE("Rect: %p T %li, L %li, B %li, R %li\n", hwnd,
rect.top, rect.left, rect.bottom, rect.right);
pti = (TCITEMW *)lParam;
iItem = (INT)wParam;
if (iItem < 0) return -1;
if (iItem > infoPtr->uNumItem)
iItem = infoPtr->uNumItem;
TAB_DumpItemExternalW(pti, iItem);
if (infoPtr->uNumItem == 0) {
infoPtr->items = Alloc (TAB_ITEM_SIZE(infoPtr));
infoPtr->uNumItem++;
infoPtr->iSelected = 0;
}
else {
TAB_ITEM *oldItems = infoPtr->items;
infoPtr->uNumItem++;
infoPtr->items = Alloc (TAB_ITEM_SIZE(infoPtr) * infoPtr->uNumItem);
/* pre insert copy */
if (iItem > 0) {
memcpy (&infoPtr->items[0], &oldItems[0],
iItem * TAB_ITEM_SIZE(infoPtr));
}
/* post insert copy */
if (iItem < infoPtr->uNumItem - 1) {
memcpy (&infoPtr->items[iItem+1], &oldItems[iItem],
(infoPtr->uNumItem - iItem - 1) * TAB_ITEM_SIZE(infoPtr));
}
if (iItem <= infoPtr->iSelected)
infoPtr->iSelected++;
Free (oldItems);
}
infoPtr->items[iItem].mask = pti->mask;
if (pti->mask & TCIF_TEXT)
Str_SetPtrW (&infoPtr->items[iItem].pszText, pti->pszText);
if (pti->mask & TCIF_IMAGE)
infoPtr->items[iItem].iImage = pti->iImage;
if (pti->mask & TCIF_PARAM)
memcpy(infoPtr->items[iItem].extra, &pti->lParam, infoPtr->cbInfo);
else
memset(infoPtr->items[iItem].extra, 0, infoPtr->cbInfo);
TAB_SetItemBounds(hwnd);
if (infoPtr->uNumItem > 1)
TAB_InvalidateTabArea(hwnd, infoPtr);
else
InvalidateRect(hwnd, NULL, TRUE);
TRACE("[%p]: added item %d %s\n",
hwnd, iItem, debugstr_w(infoPtr->items[iItem].pszText));
return iItem;
}
static LRESULT
TAB_SetItemSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
@ -2707,9 +2645,9 @@ TAB_HighlightItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
if ((infoPtr) && (iItem>=0) && (iItem<infoPtr->uNumItem)) {
if (fHighlight)
infoPtr->items[iItem].dwState |= TCIS_HIGHLIGHTED;
TAB_GetItem(infoPtr, iItem)->dwState |= TCIS_HIGHLIGHTED;
else
infoPtr->items[iItem].dwState &= ~TCIS_HIGHLIGHTED;
TAB_GetItem(infoPtr, iItem)->dwState &= ~TCIS_HIGHLIGHTED;
} else
return FALSE;
@ -2717,7 +2655,7 @@ TAB_HighlightItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
static LRESULT
TAB_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
TAB_SetItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
{
TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
TCITEMA *tabItem;
@ -2730,9 +2668,12 @@ TAB_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
TRACE("%d %p\n", iItem, tabItem);
if ((iItem<0) || (iItem>=infoPtr->uNumItem)) return FALSE;
TAB_DumpItemExternalA(tabItem, iItem);
if (bUnicode)
TAB_DumpItemExternalW((TCITEMW *)tabItem, iItem);
else
TAB_DumpItemExternalA(tabItem, iItem);
wineItem = &infoPtr->items[iItem];
wineItem = TAB_GetItem(infoPtr, iItem);
if (tabItem->mask & TCIF_IMAGE)
wineItem->iImage = tabItem->iImage;
@ -2747,49 +2688,18 @@ TAB_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
wineItem->dwState = tabItem->dwState;
if (tabItem->mask & TCIF_TEXT)
Str_SetPtrAtoW(&wineItem->pszText, tabItem->pszText);
/* Update and repaint tabs */
TAB_SetItemBounds(hwnd);
TAB_InvalidateTabArea(hwnd,infoPtr);
return TRUE;
{
if (wineItem->pszText)
{
Free(wineItem->pszText);
wineItem->pszText = NULL;
}
if (bUnicode)
Str_SetPtrW(&wineItem->pszText, (WCHAR*)tabItem->pszText);
else
Str_SetPtrAtoW(&wineItem->pszText, tabItem->pszText);
}
static LRESULT
TAB_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
TCITEMW *tabItem;
TAB_ITEM *wineItem;
INT iItem;
iItem = (INT)wParam;
tabItem = (LPTCITEMW)lParam;
TRACE("%d %p\n", iItem, tabItem);
if ((iItem<0) || (iItem>=infoPtr->uNumItem)) return FALSE;
TAB_DumpItemExternalW(tabItem, iItem);
wineItem = &infoPtr->items[iItem];
if (tabItem->mask & TCIF_IMAGE)
wineItem->iImage = tabItem->iImage;
if (tabItem->mask & TCIF_PARAM)
memcpy(wineItem->extra, &tabItem->lParam, infoPtr->cbInfo);
if (tabItem->mask & TCIF_RTLREADING)
FIXME("TCIF_RTLREADING\n");
if (tabItem->mask & TCIF_STATE)
wineItem->dwState = tabItem->dwState;
if (tabItem->mask & TCIF_TEXT)
Str_SetPtrW(&wineItem->pszText, tabItem->pszText);
/* Update and repaint tabs */
TAB_SetItemBounds(hwnd);
TAB_InvalidateTabArea(hwnd,infoPtr);
@ -2797,7 +2707,6 @@ TAB_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
return TRUE;
}
static LRESULT
TAB_GetItemCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
@ -2808,7 +2717,7 @@ TAB_GetItemCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
static LRESULT
TAB_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
TAB_GetItemAW (HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL bUnicode)
{
TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
TCITEMA *tabItem;
@ -2821,7 +2730,7 @@ TAB_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
if ((iItem<0) || (iItem>=infoPtr->uNumItem))
return FALSE;
wineItem = &infoPtr->items[iItem];
wineItem = TAB_GetItem(infoPtr, iItem);
if (tabItem->mask & TCIF_IMAGE)
tabItem->iImage = wineItem->iImage;
@ -2836,46 +2745,17 @@ TAB_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
tabItem->dwState = wineItem->dwState;
if (tabItem->mask & TCIF_TEXT)
Str_GetPtrWtoA (wineItem->pszText, tabItem->pszText, tabItem->cchTextMax);
{
if (bUnicode)
Str_GetPtrW (wineItem->pszText, (WCHAR*)tabItem->pszText, tabItem->cchTextMax);
else
Str_GetPtrWtoA (wineItem->pszText, tabItem->pszText, tabItem->cchTextMax);
}
TAB_DumpItemExternalA(tabItem, iItem);
return TRUE;
}
static LRESULT
TAB_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
TCITEMW *tabItem;
TAB_ITEM *wineItem;
INT iItem;
iItem = (INT)wParam;
tabItem = (LPTCITEMW)lParam;
TRACE("\n");
if ((iItem<0) || (iItem>=infoPtr->uNumItem))
return FALSE;
wineItem=& infoPtr->items[iItem];
if (tabItem->mask & TCIF_IMAGE)
tabItem->iImage = wineItem->iImage;
if (tabItem->mask & TCIF_PARAM)
memcpy(&tabItem->lParam, wineItem->extra, infoPtr->cbInfo);
if (tabItem->mask & TCIF_RTLREADING)
FIXME("TCIF_RTLREADING\n");
if (tabItem->mask & TCIF_STATE)
tabItem->dwState = wineItem->dwState;
if (tabItem->mask & TCIF_TEXT)
Str_GetPtrW (wineItem->pszText, tabItem->pszText, tabItem->cchTextMax);
TAB_DumpItemExternalW(tabItem, iItem);
if (bUnicode)
TAB_DumpItemExternalW((TCITEMW*)tabItem, iItem);
else
TAB_DumpItemExternalA(tabItem, iItem);
return TRUE;
}
@ -2890,20 +2770,43 @@ TAB_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
if ((iItem >= 0) && (iItem < infoPtr->uNumItem))
{
TAB_ITEM *oldItems = infoPtr->items;
TAB_ITEM *item = TAB_GetItem(infoPtr, iItem);
LPBYTE oldItems = (LPBYTE)infoPtr->items;
TAB_InvalidateTabArea(hwnd, infoPtr);
if ((item->mask & TCIF_TEXT) && item->pszText)
Free(item->pszText);
infoPtr->uNumItem--;
infoPtr->items = Alloc(TAB_ITEM_SIZE(infoPtr) * infoPtr->uNumItem);
if (iItem > 0)
memcpy(&infoPtr->items[0], &oldItems[0], iItem * TAB_ITEM_SIZE(infoPtr));
if (!infoPtr->uNumItem)
{
infoPtr->items = NULL;
if (infoPtr->iHotTracked >= 0)
{
KillTimer(hwnd, TAB_HOTTRACK_TIMER);
infoPtr->iHotTracked = -1;
}
}
else
{
infoPtr->items = Alloc(TAB_ITEM_SIZE(infoPtr) * infoPtr->uNumItem);
if (iItem < infoPtr->uNumItem)
memcpy(&infoPtr->items[iItem], &oldItems[iItem + 1],
(infoPtr->uNumItem - iItem) * TAB_ITEM_SIZE(infoPtr));
if (iItem > 0)
memcpy(infoPtr->items, oldItems, iItem * TAB_ITEM_SIZE(infoPtr));
if (iItem < infoPtr->uNumItem)
memcpy(TAB_GetItem(infoPtr, iItem),
oldItems + (iItem + 1) * TAB_ITEM_SIZE(infoPtr),
(infoPtr->uNumItem - iItem) * TAB_ITEM_SIZE(infoPtr));
if (iItem <= infoPtr->iHotTracked)
{
/* When tabs move left/up, the hot track item may change */
FIXME("Recalc hot track");
}
}
Free(oldItems);
/* Readjust the selected index */
@ -2929,17 +2832,9 @@ static LRESULT
TAB_DeleteAllItems (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
TAB_InvalidateTabArea(hwnd,infoPtr);
Free (infoPtr->items);
infoPtr->uNumItem = 0;
infoPtr->iSelected = -1;
if (infoPtr->iHotTracked >= 0)
KillTimer(hwnd, TAB_HOTTRACK_TIMER);
infoPtr->iHotTracked = -1;
TAB_SetItemBounds(hwnd);
while (infoPtr->uNumItem)
TAB_DeleteItem (hwnd, 0, 0);
return TRUE;
}
@ -3154,8 +3049,8 @@ TAB_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (infoPtr->items) {
for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) {
if (infoPtr->items[iItem].pszText)
Free (infoPtr->items[iItem].pszText);
if (TAB_GetItem(infoPtr, iItem)->pszText)
Free (TAB_GetItem(infoPtr, iItem)->pszText);
}
Free (infoPtr->items);
}
@ -3214,16 +3109,12 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return TAB_GetItemCount (hwnd, wParam, lParam);
case TCM_GETITEMA:
return TAB_GetItemA (hwnd, wParam, lParam);
case TCM_GETITEMW:
return TAB_GetItemW (hwnd, wParam, lParam);
return TAB_GetItemAW (hwnd, wParam, lParam, uMsg == TCM_GETITEMW);
case TCM_SETITEMA:
return TAB_SetItemA (hwnd, wParam, lParam);
case TCM_SETITEMW:
return TAB_SetItemW (hwnd, wParam, lParam);
return TAB_SetItemAW (hwnd, wParam, lParam, uMsg == TCM_SETITEMW);
case TCM_DELETEITEM:
return TAB_DeleteItem (hwnd, wParam, lParam);
@ -3244,10 +3135,8 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return TAB_SetCurSel (hwnd, wParam);
case TCM_INSERTITEMA:
return TAB_InsertItemA (hwnd, wParam, lParam);
case TCM_INSERTITEMW:
return TAB_InsertItemW (hwnd, wParam, lParam);
return TAB_InsertItemAW (hwnd, wParam, lParam, uMsg == TCM_INSERTITEMW);
case TCM_SETITEMEXTRA:
return TAB_SetItemExtra (hwnd, wParam, lParam);

View file

@ -45,6 +45,7 @@
* - TB_GETMETRICS
* - TB_GETOBJECT
* - TB_INSERTMARKHITTEST
* - TB_SAVERESTORE
* - TB_SETMETRICS
* - Notifications:
* - NM_CHAR
@ -1570,14 +1571,14 @@ TOOLBAR_CalcToolbar (HWND hwnd)
/* Set the toolTip only for non-hidden, non-separator button */
if (infoPtr->hwndToolTip && !(btnPtr->fsStyle & BTNS_SEP ))
{
TTTOOLINFOA ti;
TTTOOLINFOW ti;
ZeroMemory (&ti, sizeof(TTTOOLINFOA));
ti.cbSize = sizeof(TTTOOLINFOA);
ZeroMemory (&ti, sizeof(ti));
ti.cbSize = sizeof(ti);
ti.hwnd = hwnd;
ti.uId = btnPtr->idCommand;
ti.rect = btnPtr->rect;
SendMessageA (infoPtr->hwndToolTip, TTM_NEWTOOLRECTA,
SendMessageW (infoPtr->hwndToolTip, TTM_NEWTOOLRECTW,
0, (LPARAM)&ti);
}
@ -1760,7 +1761,7 @@ TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
msg.pt.x = LOWORD(GetMessagePos ());
msg.pt.y = HIWORD(GetMessagePos ());
SendMessageA (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
}
/* keeps available button list box sorted by button id */
@ -1771,50 +1772,51 @@ static void TOOLBAR_Cust_InsertAvailButton(HWND hwnd, PCUSTOMBUTTON btnInfoNew)
PCUSTOMBUTTON btnInfo;
HWND hwndAvail = GetDlgItem(hwnd, IDC_AVAILBTN_LBOX);
ERR("button %s, idCommand %d\n", debugstr_w(btnInfoNew->text), btnInfoNew->btn.idCommand);
TRACE("button %s, idCommand %d\n", debugstr_w(btnInfoNew->text), btnInfoNew->btn.idCommand);
count = SendMessageA(hwndAvail, LB_GETCOUNT, 0, 0);
count = SendMessageW(hwndAvail, LB_GETCOUNT, 0, 0);
/* position 0 is always separator */
for (i = 1; i < count; i++)
{
btnInfo = (PCUSTOMBUTTON)SendMessageA(hwndAvail, LB_GETITEMDATA, i, 0);
btnInfo = (PCUSTOMBUTTON)SendMessageW(hwndAvail, LB_GETITEMDATA, i, 0);
if (btnInfoNew->btn.idCommand < btnInfo->btn.idCommand)
{
i = SendMessageA(hwndAvail, LB_INSERTSTRING, i, 0);
SendMessageA(hwndAvail, LB_SETITEMDATA, i, (LPARAM)btnInfoNew);
i = SendMessageW(hwndAvail, LB_INSERTSTRING, i, 0);
SendMessageW(hwndAvail, LB_SETITEMDATA, i, (LPARAM)btnInfoNew);
return;
}
}
/* id higher than all others add to end */
i = SendMessageA(hwndAvail, LB_ADDSTRING, 0, 0);
SendMessageA(hwndAvail, LB_SETITEMDATA, i, (LPARAM)btnInfoNew);
i = SendMessageW(hwndAvail, LB_ADDSTRING, 0, 0);
SendMessageW(hwndAvail, LB_SETITEMDATA, i, (LPARAM)btnInfoNew);
}
static void TOOLBAR_Cust_MoveButton(PCUSTDLG_INFO custInfo, HWND hwnd, INT nIndexFrom, INT nIndexTo)
{
NMTOOLBARA nmtb;
NMTOOLBARW nmtb;
TRACE("index from %d, index to %d\n", nIndexFrom, nIndexTo);
if (nIndexFrom == nIndexTo)
return;
/* send TBN_QUERYINSERT notification */
nmtb.iItem = nIndexFrom; /* FIXME: this doesn't look right */
/* MSDN states that iItem is the index of the button, rather than the
* command ID as used by every other NMTOOLBAR notification */
nmtb.iItem = nIndexFrom;
if (TOOLBAR_SendNotify((NMHDR *)&nmtb, custInfo->tbInfo, TBN_QUERYINSERT))
{
PCUSTOMBUTTON btnInfo;
NMHDR hdr;
HWND hwndList = GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX);
int count = SendMessageA(hwndList, LB_GETCOUNT, 0, 0);
int count = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
btnInfo = (PCUSTOMBUTTON)SendMessageA(hwndList, LB_GETITEMDATA, nIndexFrom, 0);
btnInfo = (PCUSTOMBUTTON)SendMessageW(hwndList, LB_GETITEMDATA, nIndexFrom, 0);
SendMessageA(hwndList, LB_DELETESTRING, nIndexFrom, 0);
SendMessageA(hwndList, LB_INSERTSTRING, nIndexTo, 0);
SendMessageA(hwndList, LB_SETITEMDATA, nIndexTo, (LPARAM)btnInfo);
SendMessageA(hwndList, LB_SETCURSEL, nIndexTo, 0);
SendMessageW(hwndList, LB_DELETESTRING, nIndexFrom, 0);
SendMessageW(hwndList, LB_INSERTSTRING, nIndexTo, 0);
SendMessageW(hwndList, LB_SETITEMDATA, nIndexTo, (LPARAM)btnInfo);
SendMessageW(hwndList, LB_SETCURSEL, nIndexTo, 0);
if (nIndexTo <= 0)
EnableWindow(GetDlgItem(hwnd,IDC_MOVEUP_BTN), FALSE);
@ -1827,8 +1829,8 @@ static void TOOLBAR_Cust_MoveButton(PCUSTDLG_INFO custInfo, HWND hwnd, INT nInde
else
EnableWindow(GetDlgItem(hwnd,IDC_MOVEDN_BTN), TRUE);
SendMessageA(custInfo->tbHwnd, TB_DELETEBUTTON, nIndexFrom, 0);
SendMessageA(custInfo->tbHwnd, TB_INSERTBUTTONA, nIndexTo, (LPARAM)&(btnInfo->btn));
SendMessageW(custInfo->tbHwnd, TB_DELETEBUTTON, nIndexFrom, 0);
SendMessageW(custInfo->tbHwnd, TB_INSERTBUTTONW, nIndexTo, (LPARAM)&(btnInfo->btn));
TOOLBAR_SendNotify(&hdr, custInfo->tbInfo, TBN_TOOLBARCHANGE);
}
@ -1836,30 +1838,31 @@ static void TOOLBAR_Cust_MoveButton(PCUSTDLG_INFO custInfo, HWND hwnd, INT nInde
static void TOOLBAR_Cust_AddButton(PCUSTDLG_INFO custInfo, HWND hwnd, INT nIndexAvail, INT nIndexTo)
{
NMTOOLBARA nmtb;
NMTOOLBARW nmtb;
TRACE("Add: nIndexAvail %d, nIndexTo %d\n", nIndexAvail, nIndexTo);
/* send TBN_QUERYINSERT notification */
nmtb.iItem = nIndexAvail; /* FIXME: this doesn't look right */
/* MSDN states that iItem is the index of the button, rather than the
* command ID as used by every other NMTOOLBAR notification */
nmtb.iItem = nIndexAvail;
if (TOOLBAR_SendNotify((NMHDR *)&nmtb, custInfo->tbInfo, TBN_QUERYINSERT))
{
PCUSTOMBUTTON btnInfo;
NMHDR hdr;
HWND hwndList = GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX);
HWND hwndAvail = GetDlgItem(hwnd, IDC_AVAILBTN_LBOX);
int count = SendMessageA(hwndAvail, LB_GETCOUNT, 0, 0);
int count = SendMessageW(hwndAvail, LB_GETCOUNT, 0, 0);
btnInfo = (PCUSTOMBUTTON)SendMessageA(hwndAvail, LB_GETITEMDATA, nIndexAvail, 0);
btnInfo = (PCUSTOMBUTTON)SendMessageW(hwndAvail, LB_GETITEMDATA, nIndexAvail, 0);
if (nIndexAvail != 0) /* index == 0 indicates separator */
{
/* remove from 'available buttons' list */
SendMessageA(hwndAvail, LB_DELETESTRING, nIndexAvail, 0);
SendMessageW(hwndAvail, LB_DELETESTRING, nIndexAvail, 0);
if (nIndexAvail == count-1)
SendMessageA(hwndAvail, LB_SETCURSEL, nIndexAvail-1 , 0);
SendMessageW(hwndAvail, LB_SETCURSEL, nIndexAvail-1 , 0);
else
SendMessageA(hwndAvail, LB_SETCURSEL, nIndexAvail , 0);
SendMessageW(hwndAvail, LB_SETCURSEL, nIndexAvail , 0);
}
else
{
@ -1872,10 +1875,10 @@ static void TOOLBAR_Cust_AddButton(PCUSTDLG_INFO custInfo, HWND hwnd, INT nIndex
}
/* insert into 'toolbar button' list */
SendMessageA(hwndList, LB_INSERTSTRING, nIndexTo, 0);
SendMessageA(hwndList, LB_SETITEMDATA, nIndexTo, (LPARAM)btnInfo);
SendMessageW(hwndList, LB_INSERTSTRING, nIndexTo, 0);
SendMessageW(hwndList, LB_SETITEMDATA, nIndexTo, (LPARAM)btnInfo);
SendMessageA(custInfo->tbHwnd, TB_INSERTBUTTONA, nIndexTo, (LPARAM)&(btnInfo->btn));
SendMessageW(custInfo->tbHwnd, TB_INSERTBUTTONW, nIndexTo, (LPARAM)&(btnInfo->btn));
TOOLBAR_SendNotify(&hdr, custInfo->tbInfo, TBN_TOOLBARCHANGE);
}
@ -1888,17 +1891,17 @@ static void TOOLBAR_Cust_RemoveButton(PCUSTDLG_INFO custInfo, HWND hwnd, INT ind
TRACE("Remove: index %d\n", index);
btnInfo = (PCUSTOMBUTTON)SendMessageA(hwndList, LB_GETITEMDATA, index, 0);
btnInfo = (PCUSTOMBUTTON)SendMessageW(hwndList, LB_GETITEMDATA, index, 0);
/* send TBN_QUERYDELETE notification */
if (TOOLBAR_IsButtonRemovable(custInfo->tbInfo, index, btnInfo))
{
NMHDR hdr;
SendMessageA(hwndList, LB_DELETESTRING, index, 0);
SendMessageA(hwndList, LB_SETCURSEL, index , 0);
SendMessageW(hwndList, LB_DELETESTRING, index, 0);
SendMessageW(hwndList, LB_SETCURSEL, index , 0);
SendMessageA(custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
SendMessageW(custInfo->tbHwnd, TB_DELETEBUTTON, index, 0);
/* insert into 'available button' list */
if (!(btnInfo->btn.fsStyle & BTNS_SEP))
@ -1919,7 +1922,7 @@ static LRESULT TOOLBAR_Cust_ToolbarDragListNotification(PCUSTDLG_INFO custInfo,
case DL_BEGINDRAG:
{
INT nCurrentItem = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
INT nCount = SendMessageA(hwndList, LB_GETCOUNT, 0, 0);
INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
/* no dragging for last item (separator) */
if (nCurrentItem >= (nCount - 1)) return FALSE;
return TRUE;
@ -1927,7 +1930,7 @@ static LRESULT TOOLBAR_Cust_ToolbarDragListNotification(PCUSTDLG_INFO custInfo,
case DL_DRAGGING:
{
INT nCurrentItem = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
INT nCount = SendMessageA(hwndList, LB_GETCOUNT, 0, 0);
INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
/* no dragging past last item (separator) */
if ((nCurrentItem >= 0) && (nCurrentItem < (nCount - 1)))
{
@ -1954,8 +1957,8 @@ static LRESULT TOOLBAR_Cust_ToolbarDragListNotification(PCUSTDLG_INFO custInfo,
case DL_DROPPED:
{
INT nIndexTo = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
INT nIndexFrom = SendMessageA(hwndList, LB_GETCURSEL, 0, 0);
INT nCount = SendMessageA(hwndList, LB_GETCOUNT, 0, 0);
INT nIndexFrom = SendMessageW(hwndList, LB_GETCURSEL, 0, 0);
INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
if ((nIndexTo >= 0) && (nIndexTo < (nCount - 1)))
{
/* clear drag arrow */
@ -1975,13 +1978,13 @@ static LRESULT TOOLBAR_Cust_ToolbarDragListNotification(PCUSTDLG_INFO custInfo,
}
break;
}
case DL_CANCELDRAG:
case DL_CANCELDRAG:
/* Clear drag arrow */
DrawInsert(hwnd, hwndList, -1);
break;
}
return 0;
return 0;
}
/* drag list notification function for available buttons list box */
@ -1991,19 +1994,13 @@ static LRESULT TOOLBAR_Cust_AvailDragListNotification(PCUSTDLG_INFO custInfo, HW
switch (pDLI->uNotification)
{
case DL_BEGINDRAG:
{
INT nCurrentItem = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
INT nCount = SendMessageA(hwndList, LB_GETCOUNT, 0, 0);
/* no dragging for last item (separator) */
if (nCurrentItem >= (nCount - 1)) return FALSE;
return TRUE;
}
case DL_DRAGGING:
{
INT nCurrentItem = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
INT nCount = SendMessageA(hwndList, LB_GETCOUNT, 0, 0);
INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
/* no dragging past last item (separator) */
if ((nCurrentItem >= 0) && (nCurrentItem < (nCount - 1)))
if ((nCurrentItem >= 0) && (nCurrentItem < nCount))
{
DrawInsert(hwnd, hwndList, nCurrentItem);
/* FIXME: native uses "move button" cursor */
@ -2028,9 +2025,9 @@ static LRESULT TOOLBAR_Cust_AvailDragListNotification(PCUSTDLG_INFO custInfo, HW
case DL_DROPPED:
{
INT nIndexTo = LBItemFromPt(hwndList, pDLI->ptCursor, TRUE);
INT nCount = SendMessageA(hwndList, LB_GETCOUNT, 0, 0);
INT nIndexFrom = SendDlgItemMessageA(hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
if ((nIndexTo >= 0) && (nIndexTo < (nCount - 1)))
INT nCount = SendMessageW(hwndList, LB_GETCOUNT, 0, 0);
INT nIndexFrom = SendDlgItemMessageW(hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
if ((nIndexTo >= 0) && (nIndexTo < nCount))
{
/* clear drag arrow */
DrawInsert(hwnd, hwndList, -1);
@ -2038,12 +2035,12 @@ static LRESULT TOOLBAR_Cust_AvailDragListNotification(PCUSTDLG_INFO custInfo, HW
TOOLBAR_Cust_AddButton(custInfo, hwnd, nIndexFrom, nIndexTo);
}
}
case DL_CANCELDRAG:
case DL_CANCELDRAG:
/* Clear drag arrow */
DrawInsert(hwnd, hwndList, -1);
break;
}
return 0;
}
return 0;
}
extern UINT uDragListMessage;
@ -2102,11 +2099,11 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
/* send TBN_QUERYDELETE notification */
btnInfo->bRemovable = TOOLBAR_IsButtonRemovable(infoPtr, i, btnInfo);
index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, 0);
SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
index = (int)SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, 0);
SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
}
SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMHEIGHT, 0, infoPtr->nBitmapHeight + 8);
SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMHEIGHT, 0, infoPtr->nBitmapHeight + 8);
/* insert separator button into 'available buttons' list */
btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
@ -2115,8 +2112,8 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
btnInfo->bVirtual = FALSE;
btnInfo->bRemovable = TRUE;
LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
index = (int)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
index = (int)SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
/* insert all buttons into dsa */
for (i = 0;; i++)
@ -2150,7 +2147,7 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
else
{
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd,
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd,
IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
}
@ -2171,10 +2168,10 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
TOOLBAR_Cust_InsertAvailButton(hwnd, btnInfo);
}
SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMHEIGHT, 0, infoPtr->nBitmapHeight + 8);
SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMHEIGHT, 0, infoPtr->nBitmapHeight + 8);
/* select first item in the 'available' list */
SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, 0, 0);
SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_SETCURSEL, 0, 0);
/* append 'virtual' separator button to the 'toolbar buttons' list */
btnInfo = (PCUSTOMBUTTON)Alloc(sizeof(CUSTOMBUTTON));
@ -2183,18 +2180,18 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
btnInfo->bVirtual = TRUE;
btnInfo->bRemovable = FALSE;
LoadStringW (COMCTL32_hModule, IDS_SEPARATOR, btnInfo->text, 64);
index = (int)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
index = (int)SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_ADDSTRING, 0, (LPARAM)btnInfo);
SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, index, (LPARAM)btnInfo);
/* select last item in the 'toolbar' list */
SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index, 0);
SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETTOPINDEX, index, 0);
SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETCURSEL, index, 0);
SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETTOPINDEX, index, 0);
MakeDragList(GetDlgItem(hwnd, IDC_TOOLBARBTN_LBOX));
MakeDragList(GetDlgItem(hwnd, IDC_AVAILBTN_LBOX));
/* set focus and disable buttons */
PostMessageA (hwnd, WM_USER, 0, 0);
PostMessageW (hwnd, WM_USER, 0, 0);
}
return TRUE;
@ -2220,8 +2217,8 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
int count;
int index;
count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
count = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
index = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
/* send TBN_QUERYINSERT notification */
nmtb.iItem = index;
@ -2229,7 +2226,7 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
TBN_QUERYINSERT);
/* get list box item */
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, index, 0);
if (index == (count - 1))
{
@ -2261,21 +2258,21 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case IDC_MOVEUP_BTN:
{
int index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
int index = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
TOOLBAR_Cust_MoveButton(custInfo, hwnd, index, index-1);
}
break;
case IDC_MOVEDN_BTN: /* move down */
{
int index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
int index = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
TOOLBAR_Cust_MoveButton(custInfo, hwnd, index, index+1);
}
break;
case IDC_REMOVE_BTN: /* remove button */
{
int index = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
int index = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
if (LB_ERR == index)
break;
@ -2295,8 +2292,8 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
int index;
int indexto;
index = SendDlgItemMessageA(hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
indexto = SendDlgItemMessageA(hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
index = SendDlgItemMessageW(hwnd, IDC_AVAILBTN_LBOX, LB_GETCURSEL, 0, 0);
indexto = SendDlgItemMessageW(hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCURSEL, 0, 0);
TOOLBAR_Cust_AddButton(custInfo, hwnd, index, indexto);
}
@ -2314,25 +2311,25 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
int i;
/* delete items from 'toolbar buttons' listbox*/
count = SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
count = SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETCOUNT, 0, 0);
for (i = 0; i < count; i++)
{
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, i, 0);
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_GETITEMDATA, i, 0);
Free(btnInfo);
SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, 0, 0);
SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_SETITEMDATA, 0, 0);
}
SendDlgItemMessageA (hwnd, IDC_TOOLBARBTN_LBOX, LB_RESETCONTENT, 0, 0);
SendDlgItemMessageW (hwnd, IDC_TOOLBARBTN_LBOX, LB_RESETCONTENT, 0, 0);
/* delete items from 'available buttons' listbox*/
count = SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
count = SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_GETCOUNT, 0, 0);
for (i = 0; i < count; i++)
{
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, i, 0);
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_GETITEMDATA, i, 0);
Free(btnInfo);
SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, i, 0);
SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_SETITEMDATA, i, 0);
}
SendDlgItemMessageA (hwnd, IDC_AVAILBTN_LBOX, LB_RESETCONTENT, 0, 0);
SendDlgItemMessageW (hwnd, IDC_AVAILBTN_LBOX, LB_RESETCONTENT, 0, 0);
}
return TRUE;
@ -2348,7 +2345,7 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
COLORREF oldBk = 0;
/* get item data */
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageA (hwnd, wParam, LB_GETITEMDATA, (WPARAM)lpdis->itemID, 0);
btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, wParam, LB_GETITEMDATA, (WPARAM)lpdis->itemID, 0);
if (btnInfo == NULL)
{
FIXME("btnInfo invalid!\n");
@ -2476,17 +2473,17 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
/* FIXME: on windows the size of the images is 25x24 but the size of the bitmap
* in rsrc is only 24x24. Fix the bitmap (how?) and then fix this
*/
SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
SendMessageW (hwnd, TB_SETBITMAPSIZE, 0,
MAKELPARAM((WORD)24, (WORD)24));
SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
SendMessageW (hwnd, TB_SETBUTTONSIZE, 0,
MAKELPARAM((WORD)31, (WORD)30));
}
else
{
/* small icons */
SendMessageA (hwnd, TB_SETBITMAPSIZE, 0,
SendMessageW (hwnd, TB_SETBITMAPSIZE, 0,
MAKELPARAM((WORD)16, (WORD)16));
SendMessageA (hwnd, TB_SETBUTTONSIZE, 0,
SendMessageW (hwnd, TB_SETBUTTONSIZE, 0,
MAKELPARAM((WORD)22, (WORD)22));
}
@ -2704,16 +2701,16 @@ TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
btnPtr->bHot = FALSE;
if ((infoPtr->hwndToolTip) && !(btnPtr->fsStyle & BTNS_SEP)) {
TTTOOLINFOA ti;
TTTOOLINFOW ti;
ZeroMemory (&ti, sizeof(TTTOOLINFOA));
ti.cbSize = sizeof (TTTOOLINFOA);
ZeroMemory (&ti, sizeof(ti));
ti.cbSize = sizeof(ti);
ti.hwnd = hwnd;
ti.uId = btnPtr->idCommand;
ti.hinst = 0;
ti.lpszText = LPSTR_TEXTCALLBACKA;
ti.lpszText = LPSTR_TEXTCALLBACKW;
SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
0, (LPARAM)&ti);
}
}
@ -3168,16 +3165,16 @@ TOOLBAR_Customize (HWND hwnd)
TOOLBAR_SendNotify ((NMHDR *) &nmhdr, infoPtr,
TBN_BEGINADJUST);
if (!(hRes = FindResourceA (COMCTL32_hModule,
MAKEINTRESOURCEA(IDD_TBCUSTOMIZE),
(LPSTR)RT_DIALOG)))
if (!(hRes = FindResourceW (COMCTL32_hModule,
MAKEINTRESOURCEW(IDD_TBCUSTOMIZE),
(LPWSTR)RT_DIALOG)))
return FALSE;
if(!(template = (LPVOID)LoadResource (COMCTL32_hModule, hRes)))
return FALSE;
ret = DialogBoxIndirectParamA ((HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE),
(LPDLGTEMPLATEA)template,
ret = DialogBoxIndirectParamW ((HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE),
(LPDLGTEMPLATEW)template,
hwnd,
TOOLBAR_CustomizeDialogProc,
(LPARAM)&custInfo);
@ -3196,24 +3193,31 @@ TOOLBAR_DeleteButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
INT nIndex = (INT)wParam;
NMTOOLBARW nmtb;
TBUTTON_INFO *btnPtr = &infoPtr->buttons[nIndex];
if ((nIndex < 0) || (nIndex >= infoPtr->nNumButtons))
return FALSE;
return FALSE;
memset(&nmtb, 0, sizeof(nmtb));
nmtb.iItem = nIndex;
nmtb.iItem = btnPtr->idCommand;
nmtb.tbButton.iBitmap = btnPtr->iBitmap;
nmtb.tbButton.idCommand = btnPtr->idCommand;
nmtb.tbButton.fsState = btnPtr->fsState;
nmtb.tbButton.fsStyle = btnPtr->fsStyle;
nmtb.tbButton.dwData = btnPtr->dwData;
nmtb.tbButton.iString = btnPtr->iString;
TOOLBAR_SendNotify((NMHDR *)&nmtb, infoPtr, TBN_DELETINGBUTTON);
if ((infoPtr->hwndToolTip) &&
!(infoPtr->buttons[nIndex].fsStyle & BTNS_SEP)) {
TTTOOLINFOA ti;
!(btnPtr->fsStyle & BTNS_SEP)) {
TTTOOLINFOW ti;
ZeroMemory (&ti, sizeof(TTTOOLINFOA));
ti.cbSize = sizeof (TTTOOLINFOA);
ZeroMemory (&ti, sizeof(ti));
ti.cbSize = sizeof(ti);
ti.hwnd = hwnd;
ti.uId = infoPtr->buttons[nIndex].idCommand;
SendMessageA (infoPtr->hwndToolTip, TTM_DELTOOLA, 0, (LPARAM)&ti);
SendMessageW (infoPtr->hwndToolTip, TTM_DELTOOLW, 0, (LPARAM)&ti);
}
if (infoPtr->nNumButtons == 1) {
@ -3733,7 +3737,7 @@ TOOLBAR_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
TRACE("%s hwnd=%p stub!\n",
TRACE("%s hwnd=%p\n",
infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
return infoPtr->bUnicode;
@ -3879,16 +3883,16 @@ TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
infoPtr->buttons[nIndex].iString = lpTbb->iString;
if ((infoPtr->hwndToolTip) && !(lpTbb->fsStyle & BTNS_SEP)) {
TTTOOLINFOA ti;
TTTOOLINFOW ti;
ZeroMemory (&ti, sizeof(TTTOOLINFOA));
ti.cbSize = sizeof (TTTOOLINFOA);
ZeroMemory (&ti, sizeof(ti));
ti.cbSize = sizeof (ti);
ti.hwnd = hwnd;
ti.uId = lpTbb->idCommand;
ti.hinst = 0;
ti.lpszText = LPSTR_TEXTCALLBACKA;
ti.lpszText = LPSTR_TEXTCALLBACKW;
SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA,
SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW,
0, (LPARAM)&ti);
}
@ -5104,7 +5108,7 @@ TOOLBAR_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
BOOL bTemp;
TRACE("%s hwnd=%p stub!\n",
TRACE("%s hwnd=%p\n",
((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
bTemp = infoPtr->bUnicode;
@ -5361,12 +5365,12 @@ TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
infoPtr->nNumStrings = 0;
infoPtr->bCaptured = FALSE;
infoPtr->bUnicode = IsWindowUnicode (hwnd);
infoPtr->nButtonDown = -1;
infoPtr->nButtonDrag = -1;
infoPtr->nOldHit = -1;
infoPtr->nHotItem = -1;
infoPtr->hwndNotify = ((LPCREATESTRUCTW)lParam)->hwndParent;
infoPtr->bUnicode = IsWindowUnicode (infoPtr->hwndNotify);
infoPtr->bBtnTranspnt = (dwStyle & (TBSTYLE_FLAT | TBSTYLE_LIST));
infoPtr->dwDTFlags = (dwStyle & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS: DT_CENTER | DT_END_ELLIPSIS;
infoPtr->bAnchor = FALSE; /* no anchor highlighting */
@ -5508,11 +5512,11 @@ TOOLBAR_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
parent = GetParent(hwnd);
MapWindowPoints(hwnd, parent, &pt, 1);
OffsetWindowOrgEx (hdc, pt.x, pt.y, &ptorig);
ret = SendMessageA (parent, WM_ERASEBKGND, wParam, lParam);
ret = SendMessageW (parent, WM_ERASEBKGND, wParam, lParam);
SetWindowOrgEx (hdc, ptorig.x, ptorig.y, 0);
}
if (!ret)
ret = DefWindowProcA (hwnd, WM_ERASEBKGND, wParam, lParam);
ret = DefWindowProcW (hwnd, WM_ERASEBKGND, wParam, lParam);
if ((infoPtr->dwStyle & TBSTYLE_CUSTOMERASE) &&
(infoPtr->dwBaseCustDraw & CDRF_NOTIFYPOSTERASE)) {
@ -5857,7 +5861,7 @@ TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (btnPtr->fsState & TBSTATE_ENABLED)
{
SendMessageA (infoPtr->hwndNotify, WM_COMMAND,
SendMessageW (infoPtr->hwndNotify, WM_COMMAND,
MAKEWPARAM(infoPtr->buttons[nHit].idCommand, 0), (LPARAM)hwnd);
}
}
@ -6064,7 +6068,7 @@ inline static LRESULT
TOOLBAR_NCActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
/* if (wndPtr->dwStyle & CCS_NODIVIDER) */
return DefWindowProcA (hwnd, WM_NCACTIVATE, wParam, lParam);
return DefWindowProcW (hwnd, WM_NCACTIVATE, wParam, lParam);
/* else */
/* return TOOLBAR_NCPaint (wndPtr, wParam, lParam); */
}
@ -6076,7 +6080,7 @@ TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (!(GetWindowLongW(hwnd, GWL_STYLE) & CCS_NODIVIDER))
((LPRECT)lParam)->top += GetSystemMetrics(SM_CYEDGE);
return DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
return DefWindowProcW (hwnd, WM_NCCALCSIZE, wParam, lParam);
}
@ -6153,7 +6157,7 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
SetWindowLongW (hwnd, GWL_STYLE, cs->style | styleadd);
}
return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
return DefWindowProcW (hwnd, WM_NCCREATE, wParam, lParam);
}
@ -6167,7 +6171,7 @@ TOOLBAR_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (dwStyle & WS_MINIMIZE)
return 0; /* Nothing to do */
DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
DefWindowProcW (hwnd, WM_NCPAINT, wParam, lParam);
if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
return 0;
@ -6389,7 +6393,7 @@ TOOLBAR_NotifyFormat(TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
return NFR_UNICODE;
if (lParam == NF_REQUERY) {
i = SendMessageA(infoPtr->hwndNotify,
i = SendMessageW(infoPtr->hwndNotify,
WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY);
if ((i < NFR_ANSI) || (i > NFR_UNICODE)) {
ERR("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n",
@ -6638,7 +6642,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
hwnd, uMsg, /* SPY_GetMsgName(uMsg), */ wParam, lParam);
if (!TOOLBAR_GetInfoPtr(hwnd) && (uMsg != WM_NCCREATE))
return DefWindowProcA( hwnd, uMsg, wParam, lParam );
return DefWindowProcW( hwnd, uMsg, wParam, lParam );
switch (uMsg)
{
@ -7018,17 +7022,17 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_DRAWITEM:
case WM_MEASUREITEM:
case WM_VKEYTOITEM:
return SendMessageA (infoPtr->hwndNotify, uMsg, wParam, lParam);
return SendMessageW (infoPtr->hwndNotify, uMsg, wParam, lParam);
/* We see this in Outlook Express 5.x and just does DefWindowProc */
case PGM_FORWARDMOUSE:
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
default:
if ((uMsg >= WM_USER) && (uMsg < WM_APP))
ERR("unknown msg %04x wp=%08x lp=%08lx\n",
uMsg, wParam, lParam);
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
}
return 0;
}
@ -7037,25 +7041,25 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
VOID
TOOLBAR_Register (void)
{
WNDCLASSA wndClass;
WNDCLASSW wndClass;
ZeroMemory (&wndClass, sizeof(WNDCLASSA));
ZeroMemory (&wndClass, sizeof(WNDCLASSW));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
wndClass.lpfnWndProc = (WNDPROC)ToolbarWindowProc;
wndClass.lpfnWndProc = ToolbarWindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(TOOLBAR_INFO *);
wndClass.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
wndClass.lpszClassName = TOOLBARCLASSNAMEA;
wndClass.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndClass.lpszClassName = TOOLBARCLASSNAMEW;
RegisterClassA (&wndClass);
RegisterClassW (&wndClass);
}
VOID
TOOLBAR_Unregister (void)
{
UnregisterClassA (TOOLBARCLASSNAMEA, NULL);
UnregisterClassW (TOOLBARCLASSNAMEW, NULL);
}
static HIMAGELIST TOOLBAR_InsertImageList(PIMLENTRY **pies, INT *cies, HIMAGELIST himl, INT id)
@ -7172,10 +7176,12 @@ static BOOL TOOLBAR_GetButtonInfo(TOOLBAR_INFO *infoPtr, NMTOOLBARW *nmtb)
static BOOL TOOLBAR_IsButtonRemovable(TOOLBAR_INFO *infoPtr,
int iItem, PCUSTOMBUTTON btnInfo)
{
NMTOOLBARA nmtb;
NMTOOLBARW nmtb;
/* MSDN states that iItem is the index of the button, rather than the
* command ID as used by every other NMTOOLBAR notification */
nmtb.iItem = iItem;
memcpy(&nmtb.tbButton, &btnInfo->btn, sizeof(TBBUTTON));
return TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_QUERYDELETE);
return TOOLBAR_SendNotify(&nmtb.hdr, infoPtr, TBN_QUERYDELETE);
}

View file

@ -192,7 +192,7 @@ TOOLTIPS_InitSystemSettings (TOOLTIPS_INFO *infoPtr)
DeleteObject (infoPtr->hFont);
nclm.cbSize = sizeof(nclm);
SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof(nclm), &nclm, 0);
infoPtr->hFont = CreateFontIndirectW (&nclm.lfStatusFont);
DeleteObject (infoPtr->hTitleFont);
@ -318,7 +318,7 @@ static void TOOLTIPS_GetDispInfoA(HWND hwnd, TOOLTIPS_INFO *infoPtr, TTTOOL_INFO
ttnmdi.lParam = toolPtr->lParam;
TRACE("hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
SendMessageA(toolPtr->hwnd, WM_NOTIFY,
SendMessageW(toolPtr->hwnd, WM_NOTIFY,
(WPARAM)toolPtr->uId, (LPARAM)&ttnmdi);
if (HIWORD((UINT)ttnmdi.lpszText) == 0) {
@ -522,7 +522,7 @@ TOOLTIPS_Show (HWND hwnd, TOOLTIPS_INFO *infoPtr)
hdr.hwndFrom = hwnd;
hdr.idFrom = toolPtr->uId;
hdr.code = TTN_SHOW;
SendMessageA (toolPtr->hwnd, WM_NOTIFY,
SendMessageW (toolPtr->hwnd, WM_NOTIFY,
(WPARAM)toolPtr->uId, (LPARAM)&hdr);
TRACE("%s\n", debugstr_w(infoPtr->szTipText));
@ -698,7 +698,7 @@ TOOLTIPS_Hide (HWND hwnd, TOOLTIPS_INFO *infoPtr)
hdr.hwndFrom = hwnd;
hdr.idFrom = toolPtr->uId;
hdr.code = TTN_POP;
SendMessageA (toolPtr->hwnd, WM_NOTIFY,
SendMessageW (toolPtr->hwnd, WM_NOTIFY,
(WPARAM)toolPtr->uId, (LPARAM)&hdr);
infoPtr->nCurrentTool = -1;
@ -736,7 +736,7 @@ TOOLTIPS_TrackShow (HWND hwnd, TOOLTIPS_INFO *infoPtr)
hdr.hwndFrom = hwnd;
hdr.idFrom = toolPtr->uId;
hdr.code = TTN_SHOW;
SendMessageA (toolPtr->hwnd, WM_NOTIFY,
SendMessageW (toolPtr->hwnd, WM_NOTIFY,
(WPARAM)toolPtr->uId, (LPARAM)&hdr);
TRACE("%s\n", debugstr_w(infoPtr->szTipText));
@ -822,7 +822,7 @@ TOOLTIPS_TrackHide (HWND hwnd, TOOLTIPS_INFO *infoPtr)
hdr.hwndFrom = hwnd;
hdr.idFrom = toolPtr->uId;
hdr.code = TTN_POP;
SendMessageA (toolPtr->hwnd, WM_NOTIFY,
SendMessageW (toolPtr->hwnd, WM_NOTIFY,
(WPARAM)toolPtr->uId, (LPARAM)&hdr);
SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
@ -936,7 +936,7 @@ TOOLTIPS_CheckTool (HWND hwnd, BOOL bShowTest)
INT nTool;
GetCursorPos (&pt);
hwndTool = (HWND)SendMessageA (hwnd, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
hwndTool = (HWND)SendMessageW (hwnd, TTM_WINDOWFROMPOINT, 0, (LPARAM)&pt);
if (hwndTool == 0)
return -1;
@ -1048,7 +1048,7 @@ TOOLTIPS_AddToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
TRACE("subclassing installed!\n");
}
nResult = (INT) SendMessageA (toolPtr->hwnd, WM_NOTIFYFORMAT,
nResult = (INT) SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
(WPARAM)hwnd, (LPARAM)NF_QUERY);
if (nResult == NFR_ANSI) {
toolPtr->bNotifyUnicode = FALSE;
@ -1138,7 +1138,7 @@ TOOLTIPS_AddToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
TRACE("subclassing installed!\n");
}
nResult = (INT) SendMessageA (toolPtr->hwnd, WM_NOTIFYFORMAT,
nResult = (INT) SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
(WPARAM)hwnd, (LPARAM)NF_QUERY);
if (nResult == NFR_ANSI) {
toolPtr->bNotifyUnicode = FALSE;
@ -2415,7 +2415,7 @@ TOOLTIPS_NCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
}
return DefWindowProcA (hwnd, WM_NCHITTEST, wParam, lParam);
return DefWindowProcW (hwnd, WM_NCHITTEST, wParam, lParam);
}
@ -2464,8 +2464,9 @@ TOOLTIPS_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
return 0;
}
/******************************************************************
* TOOLTIPS_OnWMGetTextLength
* TOOLTIPS_GetTextLength
*
* This function is called when the tooltip receive a
* WM_GETTEXTLENGTH message.
@ -2473,12 +2474,12 @@ TOOLTIPS_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
* lParam : not used
*
* returns the length, in characters, of the tip text
******************************************************************/
*/
static LRESULT
TOOLTIPS_OnWMGetTextLength(HWND hwnd, WPARAM wParam, LPARAM lParam)
TOOLTIPS_GetTextLength(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
return lstrlenW(infoPtr->szTipText);
return strlenW(infoPtr->szTipText);
}
/******************************************************************
@ -2491,17 +2492,21 @@ TOOLTIPS_OnWMGetTextLength(HWND hwnd, WPARAM wParam, LPARAM lParam)
* the tip text
*
* returns the number of characters copied
******************************************************************/
*/
static LRESULT
TOOLTIPS_OnWMGetText (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LRESULT res;
LPWSTR pszText = (LPWSTR)lParam;
if(!infoPtr || !(infoPtr->szTipText))
if(!infoPtr->szTipText || !wParam)
return 0;
return WideCharToMultiByte(CP_ACP, 0, infoPtr->szTipText, -1,
(LPSTR)lParam, wParam, NULL, NULL);
res = min(strlenW(infoPtr->szTipText)+1, wParam);
memcpy(pszText, infoPtr->szTipText, res*sizeof(WCHAR));
pszText[res-1] = '\0';
return res-1;
}
static LRESULT
@ -2597,7 +2602,7 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);
if (!TOOLTIPS_GetInfoPtr(hwnd) && (uMsg != WM_CREATE) && (uMsg != WM_NCCREATE))
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
switch (uMsg)
{
case TTM_ACTIVATE:
@ -2741,7 +2746,7 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return TOOLTIPS_OnWMGetText (hwnd, wParam, lParam);
case WM_GETTEXTLENGTH:
return TOOLTIPS_OnWMGetTextLength (hwnd, wParam, lParam);
return TOOLTIPS_GetTextLength (hwnd, wParam, lParam);
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
@ -2777,7 +2782,7 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if ((uMsg >= WM_USER) && (uMsg < WM_APP))
ERR("unknown msg %04x wp=%08x lp=%08lx\n",
uMsg, wParam, lParam);
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
}
return 0;
}
@ -2786,18 +2791,18 @@ TOOLTIPS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
VOID
TOOLTIPS_Register (void)
{
WNDCLASSA wndClass;
WNDCLASSW wndClass;
ZeroMemory (&wndClass, sizeof(WNDCLASSA));
ZeroMemory (&wndClass, sizeof(WNDCLASSW));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
wndClass.lpfnWndProc = (WNDPROC)TOOLTIPS_WindowProc;
wndClass.lpfnWndProc = TOOLTIPS_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(TOOLTIPS_INFO *);
wndClass.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
wndClass.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
wndClass.hbrBackground = 0;
wndClass.lpszClassName = TOOLTIPS_CLASSA;
wndClass.lpszClassName = TOOLTIPS_CLASSW;
RegisterClassA (&wndClass);
RegisterClassW (&wndClass);
hTooltipIcons[TTI_NONE] = NULL;
hTooltipIcons[TTI_INFO] = LoadImageW(COMCTL32_hModule,
@ -2815,5 +2820,5 @@ TOOLTIPS_Unregister (void)
int i;
for (i = 0; i < TTI_ERROR+1; i++)
DeleteObject(hTooltipIcons[i]);
UnregisterClassA (TOOLTIPS_CLASSA, NULL);
UnregisterClassW (TOOLTIPS_CLASSW, NULL);
}

View file

@ -102,7 +102,7 @@ typedef struct tagTREEVIEW_INFO
UINT uNumItems; /* number of valid TREEVIEW_ITEMs */
INT cdmode; /* last custom draw setting */
UINT uScrollTime; /* max. time for scrolling in milliseconds */
BOOL bRedraw; /* if FALSE we validate but don't redraw in TREEVIEW_Paint() */
BOOL bRedraw; /* if FALSE we validate but don't redraw in TREEVIEW_Paint() */
UINT uItemHeight; /* item height */
BOOL bHeightSet;
@ -1077,7 +1077,7 @@ TREEVIEW_DoSetItemT(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem,
len = lstrlenW(tvItem->pszText) + 1;
else
len = MultiByteToWideChar(CP_ACP, 0, (LPSTR)tvItem->pszText, -1, NULL, 0);
newText = ReAlloc(wineItem->pszText, len * sizeof(WCHAR));
if (newText == NULL) return FALSE;
@ -1642,6 +1642,35 @@ TREEVIEW_GetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam)
}
}
#define TVHEIGHT_MIN 16
#define TVHEIGHT_FONT_ADJUST 3 /* 2 for focus border + 1 for margin some apps assume */
/* Compute the natural height for items. */
static UINT
TREEVIEW_NaturalHeight(TREEVIEW_INFO *infoPtr)
{
TEXTMETRICW tm;
HDC hdc = GetDC(0);
HFONT hOldFont = SelectObject(hdc, infoPtr->hFont);
UINT height;
/* Height is the maximum of:
* 16 (a hack because our fonts are tiny), and
* The text height + border & margin, and
* The size of the normal image list
*/
GetTextMetricsW(hdc, &tm);
SelectObject(hdc, hOldFont);
ReleaseDC(0, hdc);
height = TVHEIGHT_MIN;
if (height < tm.tmHeight + tm.tmExternalLeading + TVHEIGHT_FONT_ADJUST)
height = tm.tmHeight + tm.tmExternalLeading + TVHEIGHT_FONT_ADJUST;
if (height < infoPtr->normalImageHeight)
height = infoPtr->normalImageHeight;
return height;
}
static LRESULT
TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
{
@ -1688,6 +1717,25 @@ TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
if (oldWidth != infoPtr->normalImageWidth ||
oldHeight != infoPtr->normalImageHeight)
{
BOOL bRecalcVisible = FALSE;
if (oldHeight != infoPtr->normalImageHeight &&
!infoPtr->bHeightSet)
{
infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
bRecalcVisible = TRUE;
}
if (infoPtr->normalImageWidth > MINIMUM_INDENT &&
infoPtr->normalImageWidth != infoPtr->uIndent)
{
infoPtr->uIndent = infoPtr->normalImageWidth;
bRecalcVisible = TRUE;
}
if (bRecalcVisible)
TREEVIEW_RecalculateVisibleOrder(infoPtr, NULL);
TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
TREEVIEW_UpdateScrollBars(infoPtr);
}
@ -1697,24 +1745,6 @@ TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
return (LRESULT)himlOld;
}
/* Compute the natural height (based on the font size) for items. */
static UINT
TREEVIEW_NaturalHeight(TREEVIEW_INFO *infoPtr)
{
TEXTMETRICW tm;
HDC hdc = GetDC(0);
HFONT hOldFont = SelectObject(hdc, infoPtr->hFont);
GetTextMetricsW(hdc, &tm);
SelectObject(hdc, hOldFont);
ReleaseDC(0, hdc);
/* The 16 is a hack because our fonts are tiny. */
/* add 2 for the focus border and 1 more for margin some apps assume */
return max(16, tm.tmHeight + tm.tmExternalLeading + 3);
}
static LRESULT
TREEVIEW_SetItemHeight(TREEVIEW_INFO *infoPtr, INT newHeight)
{
@ -1967,7 +1997,7 @@ TREEVIEW_GetItemT(TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
if (tvItem->mask & TVIF_CHILDREN)
{
if (TVIF_CHILDREN==I_CHILDRENCALLBACK)
if (wineItem->cChildren==I_CHILDRENCALLBACK)
FIXME("I_CHILDRENCALLBACK not supported\n");
tvItem->cChildren = wineItem->cChildren;
}
@ -2044,7 +2074,7 @@ TREEVIEW_SetItemT(TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
if (!TREEVIEW_ValidItem(infoPtr, wineItem))
return FALSE;
/* store the orignal item values */
originalItem = *wineItem;
@ -2289,8 +2319,8 @@ TREEVIEW_DrawItemLines(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item)
HBRUSH hbr = CreateSolidBrush(infoPtr->clrBk);
HBRUSH hbrOld = SelectObject(hdc, hbr);
Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1,
centerx + rectsize + 2, centery + rectsize + 2);
Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1,
centerx + rectsize + 2, centery + rectsize + 2);
SelectObject(hdc, hbrOld);
DeleteObject(hbr);
@ -2298,13 +2328,29 @@ TREEVIEW_DrawItemLines(TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item)
SelectObject(hdc, hOldPen);
DeleteObject(hNewPen);
MoveToEx(hdc, centerx - plussize + 1, centery, NULL);
LineTo(hdc, centerx + plussize, centery);
if (!(item->state & TVIS_EXPANDED))
if (height < 16 || width < 16)
{
MoveToEx(hdc, centerx, centery - plussize + 1, NULL);
LineTo(hdc, centerx, centery + plussize);
MoveToEx(hdc, centerx - plussize + 1, centery, NULL);
LineTo(hdc, centerx + plussize, centery);
if (!(item->state & TVIS_EXPANDED))
{
MoveToEx(hdc, centerx, centery - plussize + 1, NULL);
LineTo(hdc, centerx, centery + plussize);
}
}
else
{
Rectangle(hdc, centerx - plussize + 1, centery - 1,
centerx + plussize, centery + 2);
if (!(item->state & TVIS_EXPANDED))
{
Rectangle(hdc, centerx - 1, centery - plussize + 1,
centerx + 2, centery + plussize);
SetPixel(hdc, centerx - 1, centery, infoPtr->clrBk);
SetPixel(hdc, centerx + 1, centery, infoPtr->clrBk);
}
}
}
}
@ -3779,7 +3825,7 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
{
HWND hwnd = infoPtr->hwnd;
TVHITTESTINFO ht;
BOOL bTrack;
BOOL bTrack, bDoLabelEdit;
HTREEITEM tempItem;
/* If Edit control is active - kill it and return.
@ -3812,6 +3858,13 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
bTrack = (ht.flags & TVHT_ONITEM)
&& !(infoPtr->dwStyle & TVS_DISABLEDRAGDROP);
/*
* If the style allows editing and the node is already selected
* and the click occurred on the item label...
*/
bDoLabelEdit = (infoPtr->dwStyle & TVS_EDITLABELS) &&
(ht.flags & TVHT_ONITEMLABEL) && (infoPtr->selectedItem == ht.hItem);
/* Send NM_CLICK right away */
if (!bTrack)
if (TREEVIEW_SendSimpleNotify(infoPtr, NM_CLICK))
@ -3848,12 +3901,7 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
if (bTrack && TREEVIEW_SendSimpleNotify(infoPtr, NM_CLICK))
goto setfocus;
/*
* If the style allows editing and the node is already selected
* and the click occurred on the item label...
*/
if ((infoPtr->dwStyle & TVS_EDITLABELS) &&
(ht.flags & TVHT_ONITEMLABEL) && (infoPtr->selectedItem == ht.hItem))
if (bDoLabelEdit)
{
if (infoPtr->Timer & TV_EDIT_TIMER_SET)
KillTimer(hwnd, TV_EDIT_TIMER);
@ -4319,7 +4367,7 @@ TREEVIEW_EnsureVisible(TREEVIEW_INFO *infoPtr, HTREEITEM item, BOOL bHScroll)
viscount = TREEVIEW_GetVisibleCount(infoPtr);
TRACE("%p (%s) %ld - %ld viscount(%d)\n", item, TREEVIEW_ItemName(item), item->visibleOrder,
TRACE("%p (%s) %ld - %ld viscount(%d)\n", item, TREEVIEW_ItemName(item), item->visibleOrder,
hasFirstVisible ? infoPtr->firstVisible->visibleOrder : -1, viscount);
if (hasFirstVisible)
@ -4667,7 +4715,7 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
infoPtr->treeWidth = 0;
infoPtr->treeHeight = 0;
infoPtr->uIndent = 19;
infoPtr->uIndent = MINIMUM_INDENT;
infoPtr->selectedItem = 0;
infoPtr->focusedItem = 0;
/* hotItem? */
@ -4985,21 +5033,21 @@ TREEVIEW_Notify(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand)
{
INT format;
TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand);
if (nCommand != NF_REQUERY) return 0;
format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY);
TRACE("format=%d\n", format);
if (format != NFR_ANSI && format != NFR_UNICODE) return 0;
infoPtr->bNtfUnicode = (format == NFR_UNICODE);
return format;
}
static LRESULT
TREEVIEW_Size(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{

View file

@ -511,7 +511,7 @@ static HWND UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
x = budRect.right+DEFAULT_XSEP;
}
/* first adjust the buddy to accomodate the up/down */
/* first adjust the buddy to accommodate the up/down */
SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top,
budRect.right - budRect.left, budRect.bottom - budRect.top,
SWP_NOACTIVATE|SWP_NOZORDER);
@ -524,7 +524,7 @@ static HWND UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
/*
* If the updown has a buddy border, it has to overlap with the buddy
* to look as if it is integrated with the buddy control.
* We nudge the control or change it size to overlap.
* We nudge the control or change its size to overlap.
*/
if (UPDOWN_HasBuddyBorder(infoPtr)) {
if(dwStyle & UDS_ALIGNLEFT)

View file

@ -1,14 +1,17 @@
? Makefile.ros-template
? makefile
? winehq2ros.patch
Index: comctl32.spec
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/comctl32.spec,v
retrieving revision 1.44
diff -u -r1.44 comctl32.spec
--- comctl32.spec 17 May 2004 20:51:27 -0000 1.44
+++ comctl32.spec 14 Aug 2004 19:24:23 -0000
retrieving revision 1.46
diff -u -r1.46 comctl32.spec
--- comctl32.spec 19 Oct 2004 22:59:59 -0000 1.46
+++ comctl32.spec 20 Oct 2004 08:27:55 -0000
@@ -106,13 +106,13 @@
412 stdcall RemoveWindowSubclass(long ptr long)
413 stdcall DefSubclassProc(long long long long)
414 stub -noname MirrorIcon
414 stdcall -noname MirrorIcon(ptr ptr)
-415 stdcall -noname DrawTextWrap(long wstr long ptr long) user32.DrawTextW
-416 stdcall -noname DrawTextExPrivWrap(long wstr long ptr long ptr) user32.DrawTextExW
-417 stdcall -noname ExtTextOutWrap(long long long long ptr wstr long ptr) gdi32.ExtTextOutW
@ -29,10 +32,10 @@ diff -u -r1.44 comctl32.spec
Index: listview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/listview.c,v
retrieving revision 1.392
diff -u -r1.392 listview.c
--- listview.c 12 Aug 2004 20:01:55 -0000 1.392
+++ listview.c 14 Aug 2004 19:24:27 -0000
retrieving revision 1.394
diff -u -r1.394 listview.c
--- listview.c 2 Sep 2004 23:00:53 -0000 1.394
+++ listview.c 20 Oct 2004 08:27:58 -0000
@@ -146,6 +146,7 @@
#include <assert.h>
#include <ctype.h>
@ -64,11 +67,11 @@ diff -u -r1.392 listview.c
Index: string.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/string.c,v
retrieving revision 1.4
diff -u -r1.4 string.c
--- string.c 17 May 2004 20:51:27 -0000 1.4
+++ string.c 14 Aug 2004 19:24:27 -0000
@@ -254,7 +254,7 @@
retrieving revision 1.5
diff -u -r1.5 string.c
--- string.c 22 Sep 2004 19:10:27 -0000 1.5
+++ string.c 20 Oct 2004 08:27:59 -0000
@@ -264,7 +264,7 @@
{
TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
@ -77,7 +80,7 @@ diff -u -r1.4 string.c
}
/**************************************************************************
@@ -503,7 +503,7 @@
@@ -513,7 +513,7 @@
{
TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));