Sync to Wine-20040408:

Robert Shearman <R.J.Shearman@warwick.ac.uk>
- Add cursor resource.
- Implement TB_MOVEBUTTON.
- Implement drag customise.
- Send TBN_TOOLBARCHANGE and TBN_DELETINGBUTTON.
- Spelling fixes.
- Fix subclassing to support nested messages.
- Document control completeness.
- Remove unneeded include.
- Fix TEXT define.
- Fix tabs.
- Small optimisation in DrawInsert.
- Fix LButtonDown from previous change.
- Don't use BF_ADJUST flag for dropdown buttons.
- Fix LButtonDblClk.
- Fix SetBitmapSize.
- Fix SetButtonInfo.
- Documentation update.
- Better hot item handling.
- Fix DrawMasked to always use the right image list and bitmap index.
- Document completeness.
- Finish tooltip support.
- Honour WM_SETREDRAW.
- Fix all calls of InvalidateRect.
- Implement TB_LOADIMAGES, TB_MAPACCELERATOR{A,W}, TB_MARKBUTTON and
  undocumented message 0x460.
- Better debug output of undocumented message 0x45D.
- Add support for a toolbar global iListGap.
- Make TOOLBAR_CalcToolbar and TOOLBAR_DrawButton not rely on "magic
  numbers" and calculate sizes and positions more like native.
- Rewrite drawing code.
- TTM_TRACKACTIVATE can have NULL lParam when deactivating.
- Factor out common code from TOOLTIPS_DelTool{A,W}.
- Update all indices correctly after delete.
- Unicode notification detection should be local to each tool.
- Implement TTN_GETDISPINFOW notification.
Alexandre Julliard
- Do not kill the animation thread with TerminateThread, let it finish
  properly.
- Fixed a couple of races with the animation thread.
Juan Lang <juan_lang@yahoo.com>
- Prevent negative coords for line, turn off redraw when initializing,
  document one difference in native/builtin behavior.
Francois Gouget <fgouget@free.fr>
- Assorted spelling fixes.
Mike McCormack <mike@codeweavers.com>
- Make sure the rebar size is above a minimum.
- Make sure to take account of hidden bands during layout.
- Don't calculate the redundant and unused REBAR_ROW structures.
Filip Navara <xnavara@volny.cz>
- Support for RBBS_HIDETITLE style.
Ulrich Czekalla <ulrich@codeweavers.com>
- Fix rebar band insertion and non-client calculation in pager control.
Huw Davies <huw@codeweavers.com>
- Fix dumb error from rev. 1.158.
- When setting the buddy to 0 then we must still resize the updown
  control.
- Added CS_HREDRAW.
Ge van Geldorp <gvg@reactos.com>
- Explicitly ask for image list with screen depth as ILC_COLOR can/will
  limit the depth to 4bpp now.

svn path=/trunk/; revision=9147
This commit is contained in:
Gé van Geldorp 2004-04-15 08:29:57 +00:00
parent b5c06d7dbd
commit 5f3c9e9df2
18 changed files with 1514 additions and 985 deletions

View file

@ -16,6 +16,7 @@ idb_view_small.bmp
idc_copy.cur
idc_divider.cur
idc_divideropen.cur
idc_movebutton.cur
idi_dragarrow.ico
idt_check.bmp
comctl32.spec.def

View file

@ -49,6 +49,7 @@ RC_BINARIES = \
idc_copy.cur \
idc_divider.cur \
idc_divideropen.cur \
idc_movebutton.cur \
idi_dragarrow.ico \
idt_check.bmp

View file

@ -71,6 +71,7 @@ typedef struct
LPVOID outdata;
/* data for the background mechanism */
CRITICAL_SECTION cs;
HANDLE hStopEvent;
HANDLE hThread;
UINT uTimer;
/* data for playing the file */
@ -145,9 +146,17 @@ static LRESULT ANIMATE_DoStop(ANIMATE_INFO *infoPtr)
/* should stop playing */
if (infoPtr->hThread)
{
if (!TerminateThread(infoPtr->hThread,0))
WARN("could not destroy animation thread!\n");
infoPtr->hThread = 0;
HANDLE handle = infoPtr->hThread;
TRACE("stopping animation thread\n");
SetEvent( infoPtr->hStopEvent );
LeaveCriticalSection(&infoPtr->cs); /* leave it a chance to run */
WaitForSingleObject( handle, INFINITE );
TRACE("animation thread stopped\n");
EnterCriticalSection(&infoPtr->cs);
CloseHandle( infoPtr->hThread );
CloseHandle( infoPtr->hStopEvent );
infoPtr->hThread = 0;
}
if (infoPtr->uTimer) {
KillTimer(infoPtr->hwndSelf, infoPtr->uTimer);
@ -378,33 +387,20 @@ static LRESULT ANIMATE_DrawFrame(ANIMATE_INFO* infoPtr)
static DWORD CALLBACK ANIMATE_AnimationThread(LPVOID ptr_)
{
ANIMATE_INFO* infoPtr = (ANIMATE_INFO*)ptr_;
HDC hDC;
if(!infoPtr)
{
WARN("animation structure undefined!\n");
return FALSE;
}
HANDLE event;
DWORD timeout;
while(1)
{
if(GetWindowLongA(infoPtr->hwndSelf, GWL_STYLE) & ACS_TRANSPARENT)
{
hDC = GetDC(infoPtr->hwndSelf);
/* sometimes the animation window will be destroyed in between
* by the main program, so a ReleaseDC() error msg is possible */
infoPtr->hbrushBG = (HBRUSH)SendMessageA(infoPtr->hwndNotify,
WM_CTLCOLORSTATIC, (WPARAM)hDC,
(LPARAM)infoPtr->hwndSelf);
ReleaseDC(infoPtr->hwndSelf,hDC);
}
EnterCriticalSection(&infoPtr->cs);
ANIMATE_DrawFrame(infoPtr);
timeout = infoPtr->mah.dwMicroSecPerFrame;
event = infoPtr->hStopEvent;
LeaveCriticalSection(&infoPtr->cs);
/* time is in microseconds, we should convert it to milliseconds */
Sleep((infoPtr->mah.dwMicroSecPerFrame+500)/1000);
if (WaitForSingleObject( event, (timeout+500)/1000) == WAIT_OBJECT_0)
break;
}
return TRUE;
}
@ -445,13 +441,22 @@ static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)
} else {
DWORD threadID;
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");
infoPtr->hStopEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
infoPtr->hThread = CreateThread(0,0,ANIMATE_AnimationThread,(LPVOID)infoPtr, 0, &threadID);
if(!infoPtr->hThread)
{
ERR("Could not create animation thread!\n");
return FALSE;
}
}
}

View file

@ -24,7 +24,7 @@
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Sep. 9, 2002, by Dimitrie O. Paun.
*
* Unless otherwise noted, we belive this code to be complete, as per
* 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.
*

View file

@ -106,6 +106,7 @@ extern HBRUSH COMCTL32_hPattern55AABrush;
#define IDI_DRAGARROW 501
#define IDC_COPY 502
#define IDC_MOVEBUTTON 1
/* HOTKEY internal strings */
#define HKY_NONE 2048

View file

@ -23,7 +23,7 @@
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Oct. 21, 2002, by Christian Neumair.
*
* Unless otherwise noted, we belive this code to be complete, as per
* 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.
*
@ -114,6 +114,7 @@ extern void TREEVIEW_Unregister(void);
extern void UPDOWN_Register(void);
extern void UPDOWN_Unregister(void);
static LRESULT WINAPI SubclassWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LPSTR COMCTL32_aSubclass = NULL;
HMODULE COMCTL32_hModule = 0;
@ -1108,10 +1109,10 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
/* set window procedure to our own and save the current one */
if (IsWindowUnicode (hWnd))
stack->origproc = (WNDPROC)SetWindowLongW (hWnd, GWL_WNDPROC,
(LONG)DefSubclassProc);
(LONG)SubclassWndProc);
else
stack->origproc = (WNDPROC)SetWindowLongA (hWnd, GWL_WNDPROC,
(LONG)DefSubclassProc);
(LONG)SubclassWndProc);
} else {
WNDPROC current;
if (IsWindowUnicode (hWnd))
@ -1119,7 +1120,7 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
else
current = (WNDPROC)GetWindowLongA (hWnd, GWL_WNDPROC);
if (current != DefSubclassProc) {
if (current != SubclassWndProc) {
ERR ("Application has subclassed with our procedure, then manually, then with us again. The current implementation can't handle this.\n");
return FALSE;
}
@ -1262,6 +1263,33 @@ BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR u
}
/***********************************************************************
* SubclassWndProc (internal)
*
* Window procedure for all subclassed windows.
* Saves the current subclassing stack position to support nested messages
*/
static LRESULT WINAPI SubclassWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LPSUBCLASS_INFO stack;
int stackpos;
LRESULT ret;
/* retrieve our little stack from the Properties */
stack = (LPSUBCLASS_INFO)GetPropA (hWnd, COMCTL32_aSubclass);
if (!stack) {
ERR ("Our sub classing stack got erased for %p!! Nothing we can do\n", hWnd);
return 0;
}
stackpos = stack->stackpos;
stack->stackpos = stack->stacknum;
ret = DefSubclassProc(hWnd,uMsg,wParam,lParam);
stack->stackpos = stackpos;
return ret;
}
/***********************************************************************
* DefSubclassProc [COMCTL32.413]
*

View file

@ -18,6 +18,15 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* NOTES
*
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Mar. 10, 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>
@ -27,16 +36,15 @@
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winnt.h"
#include "commctrl.h"
#include "comctl32.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
#ifndef TEXT
# define TEXT(string) string
#endif
/* for compiler compatibility we only accept literal ASCII strings */
#undef TEXT
#define TEXT(string) string
#define DRAGLIST_SUBCLASSID 0
#define DRAGLIST_SCROLLPERIOD 200
@ -50,17 +58,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
/* internal Wine specific data for the drag list control */
typedef struct _DRAGLISTDATA
{
/* are we currently in dragging mode? */
BOOL dragging;
/* are we currently in dragging mode? */
BOOL dragging;
/* cursor to use as determined by DL_DRAGGING notification.
/* cursor to use as determined by DL_DRAGGING notification.
* NOTE: as we use LoadCursor we don't have to use DeleteCursor
* when we are finished with it */
HCURSOR cursor;
HCURSOR cursor;
/* optimisation so that we don't have to load the cursor
* all of the time whilst dragging */
LRESULT last_dragging_response;
LRESULT last_dragging_response;
/* prevents flicker with drawing drag arrow */
RECT last_drag_icon_rect;
} DRAGLISTDATA;
@ -259,6 +268,9 @@ VOID WINAPI DrawInsert (HWND hwndParent, HWND hwndLB, INT nItem)
if (!GetWindowSubclass(hwndLB, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID, (DWORD_PTR*)&data))
return;
if (nItem < 0)
SetRectEmpty(&rcDragIcon);
/* prevent flicker by only redrawing when necessary */
if (!EqualRect(&rcDragIcon, &data->last_drag_icon_rect))
{
@ -266,6 +278,8 @@ VOID WINAPI DrawInsert (HWND hwndParent, HWND hwndLB, INT nItem)
RedrawWindow(hwndParent, &data->last_drag_icon_rect, NULL,
RDW_INTERNALPAINT | RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
CopyRect(&data->last_drag_icon_rect, &rcDragIcon);
if (nItem >= 0)
{
hdc = GetDC(hwndParent);
@ -275,7 +289,6 @@ VOID WINAPI DrawInsert (HWND hwndParent, HWND hwndLB, INT nItem)
ReleaseDC(hwndParent, hdc);
}
}
CopyRect(&data->last_drag_icon_rect, &rcDragIcon);
}
/***********************************************************************

View file

@ -1153,7 +1153,7 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
BitBlt(hBlendMaskDC, 0, 0, cx, cy, hBlendMaskDC, 0, 0, NOTSRCCOPY);
}
#endif
/* now apply blend to the current image given the BlendMask */
if (clrBlend == CLR_DEFAULT) clrBlend = GetSysColor (COLOR_HIGHLIGHT);
else if (clrBlend == CLR_NONE) clrBlend = GetTextColor (pimldp->hdcDst);

View file

@ -26,7 +26,7 @@
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Sep. 9, 2002, by Dimitrie O. Paun.
*
* Unless otherwise noted, we belive this code to be complete, as per
* 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.
*

View file

@ -26,7 +26,7 @@
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Oct. 21, 2002, by Dimitrie O. Paun.
*
* Unless otherwise noted, we belive this code to be complete, as per
* 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.
*

View file

@ -23,7 +23,7 @@
* This code was audited for completeness against the documented features
* of Comctl32.dll version 6.0 on Sep. 9, 2002, by Dimitrie O. Paun.
*
* Unless otherwise noted, we belive this code to be complete, as per
* 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.
*

View file

@ -1175,7 +1175,7 @@ static PADDING_INFO PROPSHEET_GetPaddingInfoWizard(HWND hwndDlg, const PropSheet
hwndControl = GetDlgItem(hwndDlg, IDC_SUNKEN_LINE);
GetWindowRect(hwndControl, &rc);
ptLine.x = 0;
ptLine.x = rc.left;
ptLine.y = rc.bottom;
ScreenToClient(hwndDlg, &ptLine);
@ -1217,6 +1217,7 @@ static BOOL PROPSHEET_CreateTabControl(HWND hwndParent,
SendMessageW(hwndTabCtrl, TCM_SETIMAGELIST, 0, (LPARAM)psInfo->hImageList);
}
SendMessageW(GetDlgItem(hwndTabCtrl, IDC_TABCONTROL), WM_SETREDRAW, 0, 0);
for (i = 0; i < nTabs; i++)
{
if ( psInfo->proppage[i].hasIcon )
@ -1232,6 +1233,7 @@ static BOOL PROPSHEET_CreateTabControl(HWND hwndParent,
item.pszText = (LPWSTR) psInfo->proppage[i].pszText;
SendMessageW(hwndTabCtrl, TCM_INSERTITEMW, (WPARAM)i, (LPARAM)&item);
}
SendMessageW(GetDlgItem(hwndTabCtrl, IDC_TABCONTROL), WM_SETREDRAW, 1, 0);
return TRUE;
}
@ -2830,6 +2832,9 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
LPCPROPSHEETPAGEW ppshpage;
int idx;
/* Using PropSheetInfoStr to store extra data doesn't match the native
* common control: native uses TCM_[GS]ETITEM
*/
SetPropW(hwnd, PropSheetInfoStr, (HANDLE)psInfo);
/*

View file

@ -213,15 +213,10 @@ typedef struct
#define DRAW_BOTTOMSEP 0x00000020
#define DRAW_CHEVRONHOT 0x00000040
#define DRAW_CHEVRONPUSHED 0x00000080
#define DRAW_LAST_IN_ROW 0x00000100
#define DRAW_FIRST_IN_ROW 0x00000200
#define NTF_INVALIDATE 0x01000000
typedef struct
{
INT istartband; /* index of first band in row */
INT iendband; /* index of last band in row */
} REBAR_ROW;
typedef struct
{
COLORREF clrBk; /* background color */
@ -257,7 +252,6 @@ typedef struct
INT ichevronhotBand; /* last band that had a hot chevron */
INT iGrabbedBand;/* band number of band whose gripper was grabbed */
REBAR_ROW *rows; /* pointer to row indexes */
REBAR_BAND *bands; /* pointer to the array of rebar bands */
} REBAR_INFO;
@ -305,6 +299,10 @@ typedef struct
/* either top or bottom */
#define REBAR_DIVIDER 2
/* minimium vertical height of a normal bar */
/* or minimum width of a CCS_VERT bar - from experiment on Win2k */
#define REBAR_MINSIZE 23
/* This is the increment that is used over the band height */
#define REBARSPACE(a) ((a->fStyle & RBBS_CHILDEDGE) ? 2*REBAR_DIVIDER : 0)
@ -675,11 +673,10 @@ static VOID
REBAR_Refresh (REBAR_INFO *infoPtr, HDC hdc)
{
REBAR_BAND *lpBand;
UINT i, oldrow;
UINT i;
if (!infoPtr->DoRedraw) return;
oldrow = infoPtr->bands[0].iRow;
for (i = 0; i < infoPtr->uNumBands; i++) {
lpBand = &infoPtr->bands[i];
@ -1674,7 +1671,7 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
#if PROBLEM2
(x < adjcx) : (y < adjcy)
#else
(adjcx - x > 4) : (adjcy - y > 4)
(adjcx - x > 5) : (adjcy - y > 4)
#endif
) &&
(infoPtr->uNumBands > 1)) {
@ -1762,39 +1759,29 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
/* ******* End Phase 2 - split rows till adjustment height full ******* */
/* ******* Start Phase 2a - create array of start and end ******* */
/* indexes by row */
/* ******* Start Phase 2a - mark first and last band in each ******* */
if (infoPtr->uNumRows != origrows) {
if (infoPtr->rows) Free (infoPtr->rows);
infoPtr->rows = Alloc (sizeof (REBAR_ROW) * infoPtr->uNumRows);
prevBand = NULL;
for (i = 0; i < infoPtr->uNumBands; i++) {
lpBand = &infoPtr->bands[i];
if (HIDDENBAND(lpBand))
continue;
if( !prevBand ) {
lpBand->fDraw |= DRAW_FIRST_IN_ROW;
prevBand = lpBand;
}
else if( prevBand->iRow == lpBand->iRow )
prevBand = lpBand;
else {
prevBand->fDraw |= DRAW_LAST_IN_ROW;
lpBand->fDraw |= DRAW_FIRST_IN_ROW;
prevBand = lpBand;
}
}
if( prevBand )
prevBand->fDraw |= DRAW_LAST_IN_ROW;
row = 0;
for (i = 0; i < infoPtr->uNumBands; i++) {
lpBand = &infoPtr->bands[i];
if (HIDDENBAND(lpBand)) continue;
if (lpBand->iRow > row) {
row++;
infoPtr->rows[row-1].istartband = i;
}
if (row == 0) {
ERR("P2a bug!!!!!!\n");
}
infoPtr->rows[row-1].iendband = i;
}
for (i = 0; i < infoPtr->uNumRows; i++) {
REBAR_ROW *p;
p = &infoPtr->rows[i];
TRACE("P2a row %d, starts %d, ends %d\n",
i+1, p->istartband, p->iendband);
}
/* ******* End Phase 2a - create array of start and end ******* */
/* indexes by row */
/* ******* End Phase 2a - mark first and last band in each ******* */
/* ******* Start Phase 2b - adjust all bands for height full ******* */
@ -1804,24 +1791,28 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
if (((infoPtr->dwStyle & CCS_VERT) ? clientcx > x : clientcy > y) &&
infoPtr->uNumBands) {
INT diff, i, iband;
INT diff, i;
UINT j;
diff = (infoPtr->dwStyle & CCS_VERT) ? clientcx - x : clientcy - y;
for (i = infoPtr->uNumRows; i >= 1; i--) {
/* if row has more than 1 band, ignore row */
if (infoPtr->rows[i-1].istartband != infoPtr->rows[i-1].iendband)
continue;
/* point to only band in row */
iband = infoPtr->rows[i-1].istartband;
lpBand = &infoPtr->bands[iband];
/* iterate backwards thru the rows */
for (i = infoPtr->uNumBands-1; i>=0; i--) {
lpBand = &infoPtr->bands[i];
if(HIDDENBAND(lpBand)) continue;
/* if row has more than 1 band, ignore it */
if( !(lpBand->fDraw&DRAW_FIRST_IN_ROW) )
continue;
if( !(lpBand->fDraw&DRAW_LAST_IN_ROW) )
continue;
if (lpBand->fMask & RBBS_VARIABLEHEIGHT) continue;
if (((INT)lpBand->cyMaxChild < 1) ||
((INT)lpBand->cyIntegral < 1)) {
if (lpBand->cyMaxChild + lpBand->cyIntegral == 0) continue;
ERR("P2b band %u RBBS_VARIABLEHEIGHT set but cyMax=%d, cyInt=%d\n",
iband, lpBand->cyMaxChild, lpBand->cyIntegral);
i, lpBand->cyMaxChild, lpBand->cyIntegral);
continue;
}
/* j is now the maximum height/width in the client area */
@ -1835,7 +1826,7 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
else
lpBand->rcBand.bottom = lpBand->rcBand.top + j;
TRACE("P2b band %d, row %d changed to (%ld,%ld)-(%ld,%ld)\n",
iband, lpBand->iRow,
i, lpBand->iRow,
lpBand->rcBand.left, lpBand->rcBand.top,
lpBand->rcBand.right, lpBand->rcBand.bottom);
if (diff <= 0) break;
@ -1856,7 +1847,7 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
/* ******* Start Phase 3 - adjust all bands for width full ******* */
if (infoPtr->uNumBands) {
REBAR_ROW *p;
int startband;
/* If RBS_BANDBORDERS set then indicate to draw bottom separator */
/* on all bands in all rows but last row. */
@ -1864,39 +1855,49 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
/* each row but the rightmost band. */
if (infoPtr->dwStyle & RBS_BANDBORDERS) {
for(i = 0; i < infoPtr->uNumRows; i++) {
p = &infoPtr->rows[i];
for (j = p->istartband; j <= p->iendband; j++) {
lpBand = &infoPtr->bands[j];
if (HIDDENBAND(lpBand)) continue;
if (j != p->iendband)
lpBand->fDraw |= DRAW_RIGHTSEP;
if (i != infoPtr->uNumRows-1)
lpBand->fDraw |= DRAW_BOTTOMSEP;
}
for (i=0; i<infoPtr->uNumBands; i++) {
lpBand = &infoPtr->bands[i];
if (HIDDENBAND(lpBand))
continue;
/* not righthand bands */
if( !(lpBand->fDraw & DRAW_LAST_IN_ROW) )
lpBand->fDraw |= DRAW_RIGHTSEP;
/* not the last row */
if( lpBand->iRow != infoPtr->uNumRows )
lpBand->fDraw |= DRAW_BOTTOMSEP;
}
}
/* Distribute the extra space on the horizontal and adjust */
/* all bands in row to same height. */
for (i=1; i<=infoPtr->uNumRows; i++) {
p = &infoPtr->rows[i-1];
mcy = 0;
mcy = 0;
startband = -1;
for (i=0; i<infoPtr->uNumBands; i++) {
TRACE("P3 processing row %d, starting band %d, ending band %d\n",
i, p->istartband, p->iendband);
lpBand = &infoPtr->bands[i];
/* Find the largest height of the bands in the row */
for (j = p->istartband; j <= p->iendband; j++) {
lpBand = &infoPtr->bands[j];
if (HIDDENBAND(lpBand)) continue;
if (mcy < ircBw(lpBand))
mcy = ircBw(lpBand);
}
if( lpBand->fDraw & DRAW_FIRST_IN_ROW )
{
startband = i;
mcy = 0;
}
REBAR_AdjustBands (infoPtr, p->istartband, p->iendband,
if ( (mcy < ircBw(lpBand)) && !HIDDENBAND(lpBand) )
mcy = ircBw(lpBand);
if( lpBand->fDraw & DRAW_LAST_IN_ROW )
{
TRACE("P3 processing row %d, starting band %d, ending band %d\n",
lpBand->iRow, startband, i);
if( startband < 0 )
ERR("Last band %d with no first, row %d\n", i, lpBand->iRow);
REBAR_AdjustBands (infoPtr, startband, i,
(infoPtr->dwStyle & CCS_VERT) ?
clientcy : clientcx, mcy);
}
}
/* Calculate the other rectangles in each band */
@ -1920,6 +1921,8 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
y = clientcy;
}
if (infoPtr->dwStyle & CCS_VERT) {
if( x < REBAR_MINSIZE )
x = REBAR_MINSIZE;
infoPtr->calcSize.cx = x;
infoPtr->calcSize.cy = clientcy;
TRACE("vert, notify=%d, x=%d, origheight=%d\n",
@ -1927,6 +1930,8 @@ REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
if (notify && (x != origheight)) infoPtr->fStatus |= NTF_HGHTCHG;
}
else {
if( y < REBAR_MINSIZE )
y = REBAR_MINSIZE;
infoPtr->calcSize.cx = clientcx;
infoPtr->calcSize.cy = y;
TRACE("horz, notify=%d, y=%d, origheight=%d\n",
@ -2511,13 +2516,13 @@ REBAR_HandleLRDrag (REBAR_INFO *infoPtr, POINTS *ptsmove)
}
}
if (RHeaderSum) RHeaderSum -= SEP_WIDTH; /* no separator afterlast band */
if (RHeaderSum) RHeaderSum -= SEP_WIDTH; /* no separator after last band */
mindBand = &infoPtr->bands[imindBand];
maxdBand = &infoPtr->bands[imaxdBand];
if (imindBand == imaxdBand) return; /* nothing to drag agains */
if (imindBand == ihitBand) return; /* first band in row, cant drag */
if (imindBand == imaxdBand) return; /* nothing to drag against */
if (imindBand == ihitBand) return; /* first band in row, can't drag */
/* limit movement to inside adjustable bands - Left */
if ( (ptsmove->x < mindBand->rcBand.left) ||
@ -3205,9 +3210,9 @@ REBAR_InsertBandW (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
}
/* post copy */
if (uIndex < infoPtr->uNumBands - 1) {
if (uIndex <= infoPtr->uNumBands - 1) {
memcpy (&infoPtr->bands[uIndex+1], &oldBands[uIndex],
(infoPtr->uNumBands - uIndex - 1) * sizeof(REBAR_BAND));
(infoPtr->uNumBands - uIndex) * sizeof(REBAR_BAND));
}
Free (oldBands);
@ -3239,7 +3244,7 @@ REBAR_InsertBandW (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
REBAR_ValidateBand (infoPtr, lpBand);
/* On insert of second band, revalidate band 1 to possible add gripper */
if (infoPtr->uNumBands == 2)
REBAR_ValidateBand (infoPtr, &infoPtr->bands[0]);
REBAR_ValidateBand (infoPtr, &infoPtr->bands[uIndex ? 0 : 1]);
REBAR_DumpBand (infoPtr);

View file

@ -1052,6 +1052,33 @@ IDC_DIVIDEROPEN CURSOR LOADONCALL DISCARDABLE idc_divideropen.cur
} */
/* BINRES idc_movebutton.cur */
IDC_MOVEBUTTON CURSOR LOADONCALL DISCARDABLE idc_movebutton.cur
/* {
'00 00 02 00 01 00 20 20 00 00 10 00 10 00 30 01'
'00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
'00 00 01 00 01 00 00 00 00 00 00 01 00 00 00 00'
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
'00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
'00 00 00 00 00 00 00 00 00 00 00 0F F8 00 00 0F'
'F8 00 00 1F FC 00 00 1F FC 00 00 3F FC 00 00 3F'
'FE 00 00 7F FE 00 00 5F FE 00 00 DF FE 00 01 DF'
'FE 00 01 9F FE 00 00 1D B6 00 00 1D B4 00 00 0D'
'B0 00 00 01 80 00 00 00 00 00 00 00 00 00 00 00'
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
'00 00 00 00 00 00 FF FF FF FF FF FF FF FF D2 49'
'24 93 DF FF FF FF FF FF FF FB DF FF FF FB DF FF'
'FF FF FF FF FF FB DF E0 03 FB DF E0 03 FF FF E0'
'03 FB DF C0 01 FB DF C0 01 FF FF 80 01 FB DF 80'
'00 FB DF 00 00 FF FF 00 00 FB DE 00 00 FB DC 00'
'00 FF FC 00 00 FB DC 40 00 FB DF C0 01 FF FF E0'
'03 FB DF F0 0F FB DF FE 7F FF FF FF FF FB DF FF'
'FF FB DF FF FF FF FF FF FF FB C9 24 92 4B FF FF'
'FF FF FF FF FF FF'
} */
/* BINRES idi_dragarrow.ico */
IDI_DRAGARROW ICON LOADONCALL DISCARDABLE idi_dragarrow.ico
/* {

File diff suppressed because it is too large Load diff

View file

@ -18,8 +18,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* TODO:
* - Unicode support (started).
* - Custom draw support.
* - Balloon tips.
* - Messages.
*
* Testing:
* - Run tests using Waite Group Windows95 API Bible Volume 2.
@ -90,6 +91,7 @@ typedef struct
{
UINT uFlags;
HWND hwnd;
BOOL bNotifyUnicode;
UINT uId;
RECT rect;
HINSTANCE hinst;
@ -110,14 +112,13 @@ typedef struct
INT xTrackPos;
INT yTrackPos;
INT nMaxTipWidth;
INT nTool;
INT nTool; /* tool that mouse was on on last relayed mouse move */
INT nCurrentTool;
INT nTrackTool;
INT nReshowTime;
INT nAutoPopTime;
INT nInitialTime;
RECT rcMargin;
BOOL bNotifyUnicode;
TTTOOL_INFO *tools;
} TOOLTIPS_INFO;
@ -171,6 +172,100 @@ TOOLTIPS_Refresh (HWND hwnd, HDC hdc)
SetBkMode (hdc, oldBkMode);
}
static void TOOLTIPS_GetDispInfoA(HWND hwnd, TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr)
{
NMTTDISPINFOA ttnmdi;
/* fill NMHDR struct */
ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFOA));
ttnmdi.hdr.hwndFrom = hwnd;
ttnmdi.hdr.idFrom = toolPtr->uId;
ttnmdi.hdr.code = TTN_GETDISPINFOA;
ttnmdi.lpszText = (LPSTR)&ttnmdi.szText;
ttnmdi.uFlags = toolPtr->uFlags;
ttnmdi.lParam = toolPtr->lParam;
TRACE("hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
SendMessageA(toolPtr->hwnd, WM_NOTIFY,
(WPARAM)toolPtr->uId, (LPARAM)&ttnmdi);
if (HIWORD((UINT)ttnmdi.lpszText) == 0) {
LoadStringW(ttnmdi.hinst, (UINT)ttnmdi.lpszText,
infoPtr->szTipText, INFOTIPSIZE);
if (ttnmdi.uFlags & TTF_DI_SETITEM) {
toolPtr->hinst = ttnmdi.hinst;
toolPtr->lpszText = (LPWSTR)ttnmdi.lpszText;
}
}
else if (ttnmdi.lpszText == 0) {
/* no text available */
infoPtr->szTipText[0] = '\0';
}
else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) {
INT max_len = (ttnmdi.lpszText == &ttnmdi.szText[0]) ?
sizeof(ttnmdi.szText)/sizeof(ttnmdi.szText[0]) : -1;
MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText, max_len,
infoPtr->szTipText, INFOTIPSIZE);
if (ttnmdi.uFlags & TTF_DI_SETITEM) {
INT len = MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText,
max_len, NULL, 0);
toolPtr->hinst = 0;
toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText, -1,
toolPtr->lpszText, len);
}
}
else {
ERR("recursive text callback!\n");
infoPtr->szTipText[0] = '\0';
}
}
static void TOOLTIPS_GetDispInfoW(HWND hwnd, TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr)
{
NMTTDISPINFOW ttnmdi;
/* fill NMHDR struct */
ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFOW));
ttnmdi.hdr.hwndFrom = hwnd;
ttnmdi.hdr.idFrom = toolPtr->uId;
ttnmdi.hdr.code = TTN_GETDISPINFOW;
ttnmdi.lpszText = (LPWSTR)&ttnmdi.szText;
ttnmdi.uFlags = toolPtr->uFlags;
ttnmdi.lParam = toolPtr->lParam;
TRACE("hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
SendMessageW(toolPtr->hwnd, WM_NOTIFY,
(WPARAM)toolPtr->uId, (LPARAM)&ttnmdi);
if (HIWORD((UINT)ttnmdi.lpszText) == 0) {
LoadStringW(ttnmdi.hinst, (UINT)ttnmdi.lpszText,
infoPtr->szTipText, INFOTIPSIZE);
if (ttnmdi.uFlags & TTF_DI_SETITEM) {
toolPtr->hinst = ttnmdi.hinst;
toolPtr->lpszText = ttnmdi.lpszText;
}
}
else if (ttnmdi.lpszText == 0) {
/* no text available */
infoPtr->szTipText[0] = '\0';
}
else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKW) {
INT max_len = (ttnmdi.lpszText == &ttnmdi.szText[0]) ?
sizeof(ttnmdi.szText)/sizeof(ttnmdi.szText[0]) : INFOTIPSIZE-1;
strncpyW(infoPtr->szTipText, ttnmdi.lpszText, max_len);
if (ttnmdi.uFlags & TTF_DI_SETITEM) {
INT len = max(strlenW(ttnmdi.lpszText), max_len);
toolPtr->hinst = 0;
toolPtr->lpszText = Alloc ((len+1) * sizeof(WCHAR));
memcpy(toolPtr->lpszText, ttnmdi.lpszText, (len+1) * sizeof(WCHAR));
}
}
else {
ERR("recursive text callback!\n");
infoPtr->szTipText[0] = '\0';
}
}
static VOID
TOOLTIPS_GetTipText (HWND hwnd, TOOLTIPS_INFO *infoPtr, INT nTool)
@ -186,61 +281,10 @@ TOOLTIPS_GetTipText (HWND hwnd, TOOLTIPS_INFO *infoPtr, INT nTool)
}
else if (toolPtr->lpszText) {
if (toolPtr->lpszText == LPSTR_TEXTCALLBACKW) {
NMTTDISPINFOA ttnmdi;
/* fill NMHDR struct */
ZeroMemory (&ttnmdi, sizeof(NMTTDISPINFOA));
ttnmdi.hdr.hwndFrom = hwnd;
ttnmdi.hdr.idFrom = toolPtr->uId;
ttnmdi.hdr.code = TTN_GETDISPINFOA;
ttnmdi.lpszText = (LPSTR)&ttnmdi.szText;
ttnmdi.uFlags = toolPtr->uFlags;
ttnmdi.lParam = toolPtr->lParam;
TRACE("hdr.idFrom = %x\n", ttnmdi.hdr.idFrom);
SendMessageA (toolPtr->hwnd, WM_NOTIFY,
(WPARAM)toolPtr->uId, (LPARAM)&ttnmdi);
if (HIWORD((UINT)ttnmdi.lpszText) == 0) {
LoadStringW (ttnmdi.hinst, (UINT)ttnmdi.lpszText,
infoPtr->szTipText, INFOTIPSIZE);
if (ttnmdi.uFlags & TTF_DI_SETITEM) {
toolPtr->hinst = ttnmdi.hinst;
toolPtr->lpszText = (LPWSTR)ttnmdi.lpszText;
}
}
else if (ttnmdi.szText[0]) {
MultiByteToWideChar(CP_ACP, 0, ttnmdi.szText, 80,
infoPtr->szTipText, INFOTIPSIZE);
if (ttnmdi.uFlags & TTF_DI_SETITEM) {
INT len = MultiByteToWideChar(CP_ACP, 0, ttnmdi.szText,
80, NULL, 0);
toolPtr->hinst = 0;
toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, ttnmdi.szText, 80,
toolPtr->lpszText, len);
}
}
else if (ttnmdi.lpszText == 0) {
/* no text available */
infoPtr->szTipText[0] = L'\0';
}
else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) {
MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText, -1,
infoPtr->szTipText, INFOTIPSIZE);
if (ttnmdi.uFlags & TTF_DI_SETITEM) {
INT len = MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText,
-1, NULL, 0);
toolPtr->hinst = 0;
toolPtr->lpszText = Alloc (len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, ttnmdi.lpszText, -1,
toolPtr->lpszText, len);
}
}
else {
ERR("recursive text callback!\n");
infoPtr->szTipText[0] = '\0';
}
if (toolPtr->bNotifyUnicode)
TOOLTIPS_GetDispInfoW(hwnd, infoPtr, toolPtr);
else
TOOLTIPS_GetDispInfoA(hwnd, infoPtr, toolPtr);
}
else {
/* the item is a usual (unicode) text */
@ -502,11 +546,12 @@ TOOLTIPS_TrackHide (HWND hwnd, TOOLTIPS_INFO *infoPtr)
TTTOOL_INFO *toolPtr;
NMHDR hdr;
TRACE("hide tracking tooltip %d\n", infoPtr->nTrackTool);
if (infoPtr->nTrackTool == -1)
return;
toolPtr = &infoPtr->tools[infoPtr->nTrackTool];
TRACE("hide tracking tooltip %d!\n", infoPtr->nTrackTool);
hdr.hwndFrom = hwnd;
hdr.idFrom = toolPtr->uId;
@ -668,6 +713,7 @@ TOOLTIPS_AddToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
TTTOOL_INFO *toolPtr;
INT nResult;
if (lpToolInfo == NULL)
return FALSE;
@ -736,6 +782,18 @@ TOOLTIPS_AddToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
TRACE("subclassing installed!\n");
}
nResult = (INT) SendMessageA (toolPtr->hwnd, WM_NOTIFYFORMAT,
(WPARAM)hwnd, (LPARAM)NF_QUERY);
if (nResult == NFR_ANSI) {
toolPtr->bNotifyUnicode = FALSE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
} else if (nResult == NFR_UNICODE) {
toolPtr->bNotifyUnicode = TRUE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
} else {
TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
}
return TRUE;
}
@ -746,6 +804,7 @@ TOOLTIPS_AddToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
TTTOOL_INFO *toolPtr;
INT nResult;
if (lpToolInfo == NULL)
return FALSE;
@ -813,16 +872,102 @@ TOOLTIPS_AddToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
TRACE("subclassing installed!\n");
}
nResult = (INT) SendMessageA (toolPtr->hwnd, WM_NOTIFYFORMAT,
(WPARAM)hwnd, (LPARAM)NF_QUERY);
if (nResult == NFR_ANSI) {
toolPtr->bNotifyUnicode = FALSE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
} else if (nResult == NFR_UNICODE) {
toolPtr->bNotifyUnicode = TRUE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
} else {
TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
}
return TRUE;
}
static void TOOLTIPS_DelToolCommon (HWND hwnd, TOOLTIPS_INFO *infoPtr, INT nTool)
{
TTTOOL_INFO *toolPtr;
TRACE("tool %d\n", nTool);
if (nTool == -1)
return;
/* make sure the tooltip has disappeared before deleting it */
TOOLTIPS_Hide(hwnd, infoPtr);
/* delete text string */
toolPtr = &infoPtr->tools[nTool];
if (toolPtr->lpszText) {
if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
(HIWORD((INT)toolPtr->lpszText) != 0) )
Free (toolPtr->lpszText);
}
/* remove subclassing */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1);
}
else {
RemoveWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1);
}
}
/* delete tool from tool list */
if (infoPtr->uNumTools == 1) {
Free (infoPtr->tools);
infoPtr->tools = NULL;
}
else {
TTTOOL_INFO *oldTools = infoPtr->tools;
infoPtr->tools =
Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
if (nTool > 0)
memcpy (&infoPtr->tools[0], &oldTools[0],
nTool * sizeof(TTTOOL_INFO));
if (nTool < infoPtr->uNumTools - 1)
memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
(infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
Free (oldTools);
}
/* update any indices affected by delete */
/* destroying tool that mouse was on on last relayed mouse move */
if (infoPtr->nTool == nTool)
/* -1 means no current tool (0 means first tool) */
infoPtr->nTool = -1;
else if (infoPtr->nTool > nTool)
infoPtr->nTool--;
if (infoPtr->nTrackTool == nTool)
/* -1 means no current tool (0 means first tool) */
infoPtr->nTrackTool = -1;
else if (infoPtr->nTrackTool > nTool)
infoPtr->nTrackTool--;
if (infoPtr->nCurrentTool == nTool)
/* -1 means no current tool (0 means first tool) */
infoPtr->nCurrentTool = -1;
else if (infoPtr->nCurrentTool > nTool)
infoPtr->nCurrentTool--;
infoPtr->uNumTools--;
}
static LRESULT
TOOLTIPS_DelToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
TTTOOL_INFO *toolPtr;
INT nTool;
if (lpToolInfo == NULL)
@ -833,60 +978,8 @@ TOOLTIPS_DelToolA (HWND hwnd, WPARAM wParam, LPARAM lParam)
return 0;
nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
if (nTool == -1) return 0;
TRACE("tool %d\n", nTool);
/* make sure the tooltip has disappeared before deleting it */
TOOLTIPS_Hide(hwnd, infoPtr);
/* delete text string */
toolPtr = &infoPtr->tools[nTool];
if (toolPtr->lpszText) {
if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
(HIWORD((INT)toolPtr->lpszText) != 0) )
Free (toolPtr->lpszText);
}
/* remove subclassing */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1);
}
else {
RemoveWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1);
}
}
/* delete tool from tool list */
if (infoPtr->uNumTools == 1) {
Free (infoPtr->tools);
infoPtr->tools = NULL;
}
else {
TTTOOL_INFO *oldTools = infoPtr->tools;
infoPtr->tools =
Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
if (nTool > 0)
memcpy (&infoPtr->tools[0], &oldTools[0],
nTool * sizeof(TTTOOL_INFO));
if (nTool < infoPtr->uNumTools - 1)
memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
(infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
Free (oldTools);
}
/* destroying tool that mouse was on on last relayed mouse move */
if (infoPtr->nTool == nTool)
{
/* no current tool (0 means first tool) */
infoPtr->nTool = -1;
}
infoPtr->uNumTools--;
TOOLTIPS_DelToolCommon (hwnd, infoPtr, nTool);
return 0;
}
@ -897,7 +990,6 @@ TOOLTIPS_DelToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOW lpToolInfo = (LPTTTOOLINFOW)lParam;
TTTOOL_INFO *toolPtr;
INT nTool;
if (lpToolInfo == NULL)
@ -908,60 +1000,8 @@ TOOLTIPS_DelToolW (HWND hwnd, WPARAM wParam, LPARAM lParam)
return 0;
nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpToolInfo);
if (nTool == -1) return 0;
TRACE("tool %d\n", nTool);
/* make sure the tooltip has disappeared before deleting it */
TOOLTIPS_Hide(hwnd, infoPtr);
/* delete text string */
toolPtr = &infoPtr->tools[nTool];
if (toolPtr->lpszText) {
if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
(HIWORD((INT)toolPtr->lpszText) != 0) )
Free (toolPtr->lpszText);
}
/* remove subclassing */
if (toolPtr->uFlags & TTF_SUBCLASS) {
if (toolPtr->uFlags & TTF_IDISHWND) {
RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1);
}
else {
RemoveWindowSubclass(toolPtr->hwnd, TOOLTIPS_SubclassProc, 1);
}
}
/* delete tool from tool list */
if (infoPtr->uNumTools == 1) {
Free (infoPtr->tools);
infoPtr->tools = NULL;
}
else {
TTTOOL_INFO *oldTools = infoPtr->tools;
infoPtr->tools =
Alloc (sizeof(TTTOOL_INFO) * (infoPtr->uNumTools - 1));
if (nTool > 0)
memcpy (&infoPtr->tools[0], &oldTools[0],
nTool * sizeof(TTTOOL_INFO));
if (nTool < infoPtr->uNumTools - 1)
memcpy (&infoPtr->tools[nTool], &oldTools[nTool + 1],
(infoPtr->uNumTools - nTool - 1) * sizeof(TTTOOL_INFO));
Free (oldTools);
}
/* destroying tool that mouse was on on last relayed mouse move */
if (infoPtr->nTool == nTool)
{
/* no current tool (0 means first tool) */
infoPtr->nTool = -1;
}
infoPtr->uNumTools--;
TOOLTIPS_DelToolCommon (hwnd, infoPtr, nTool);
return 0;
}
@ -1413,6 +1453,9 @@ TOOLTIPS_NewToolRectA (HWND hwnd, WPARAM wParam, LPARAM lParam)
return FALSE;
nTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpti);
TRACE("nTool = %d, rect = %s\n", nTool, wine_dbgstr_rect(&lpti->rect));
if (nTool == -1) return 0;
infoPtr->tools[nTool].rect = lpti->rect;
@ -1434,6 +1477,9 @@ TOOLTIPS_NewToolRectW (HWND hwnd, WPARAM wParam, LPARAM lParam)
return FALSE;
nTool = TOOLTIPS_GetToolFromInfoW (infoPtr, lpti);
TRACE("nTool = %d, rect = %s\n", nTool, wine_dbgstr_rect(&lpti->rect));
if (nTool == -1) return 0;
infoPtr->tools[nTool].rect = lpti->rect;
@ -1721,14 +1767,15 @@ static LRESULT
TOOLTIPS_TrackActivate (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLTIPS_INFO *infoPtr = TOOLTIPS_GetInfoPtr (hwnd);
LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
if (lpToolInfo == NULL)
return 0;
if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
return FALSE;
if ((BOOL)wParam) {
LPTTTOOLINFOA lpToolInfo = (LPTTTOOLINFOA)lParam;
if (lpToolInfo == NULL)
return 0;
if (lpToolInfo->cbSize < TTTOOLINFOA_V1_SIZE)
return FALSE;
/* activate */
infoPtr->nTrackTool = TOOLTIPS_GetToolFromInfoA (infoPtr, lpToolInfo);
if (infoPtr->nTrackTool != -1) {
@ -1906,7 +1953,6 @@ TOOLTIPS_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
{
TOOLTIPS_INFO *infoPtr;
NONCLIENTMETRICSA nclm;
INT nResult;
/* allocate memory for info structure */
infoPtr = (TOOLTIPS_INFO *)Alloc (sizeof(TOOLTIPS_INFO));
@ -1929,18 +1975,6 @@ TOOLTIPS_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
TOOLTIPS_SetDelayTime(hwnd, TTDT_AUTOMATIC, 0L);
nResult = (INT) SendMessageA (lpcs->hwndParent, WM_NOTIFYFORMAT,
(WPARAM)hwnd, (LPARAM)NF_QUERY);
if (nResult == NFR_ANSI) {
infoPtr->bNotifyUnicode = FALSE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
} else if (nResult == NFR_UNICODE) {
infoPtr->bNotifyUnicode = TRUE;
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
} else {
TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
}
SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE);
return 0;

View file

@ -442,98 +442,109 @@ UPDOWN_Buddy_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
/***********************************************************************
* UPDOWN_SetBuddy
* Tests if 'bud' is a valid window handle. If not, returns FALSE.
* Else, sets it as a new Buddy.
*
* Sets bud as a new Buddy.
* Then, it should subclass the buddy
* If window has the UDS_ARROWKEYS, it subcalsses the buddy window to
* process the UP/DOWN arrow keys.
* If window has the UDS_ALIGNLEFT or UDS_ALIGNRIGHT style
* the size/pos of the buddy and the control are adjusted accordingly.
*/
static BOOL UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
static HWND UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
{
DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
RECT budRect; /* new coord for the buddy */
int x, width; /* new x position and width for the up-down */
WNDPROC baseWndProc;
CHAR buddyClass[40];
/* Is it a valid bud? */
if(!IsWindow(bud)) return FALSE;
HWND ret;
TRACE("(hwnd=%p, bud=%p)\n", infoPtr->Self, bud);
ret = infoPtr->Buddy;
/* there is already a body assigned */
if (infoPtr->Buddy) RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
if(!IsWindow(bud))
bud = 0;
/* Store buddy window handle */
infoPtr->Buddy = bud;
/* keep upDown ctrl hwnd in a buddy property */
SetPropA( bud, BUDDY_UPDOWN_HWND, infoPtr->Self);
if(bud) {
/* Store buddy window class type */
infoPtr->BuddyType = BUDDY_TYPE_UNKNOWN;
if (GetClassNameA(bud, buddyClass, COUNT_OF(buddyClass))) {
if (lstrcmpiA(buddyClass, "Edit") == 0)
infoPtr->BuddyType = BUDDY_TYPE_EDIT;
else if (lstrcmpiA(buddyClass, "Listbox") == 0)
infoPtr->BuddyType = BUDDY_TYPE_LISTBOX;
}
/* keep upDown ctrl hwnd in a buddy property */
SetPropA( bud, BUDDY_UPDOWN_HWND, infoPtr->Self);
if(dwStyle & UDS_ARROWKEYS){
/* Note that I don't clear the BUDDY_SUPERCLASS_WNDPROC property
when we reset the upDown ctrl buddy to another buddy because it is not
good to break the window proc chain. */
if (!GetPropA(bud, BUDDY_SUPERCLASS_WNDPROC)) {
baseWndProc = (WNDPROC)SetWindowLongW(bud, GWL_WNDPROC, (LPARAM)UPDOWN_Buddy_SubclassProc);
SetPropA(bud, BUDDY_SUPERCLASS_WNDPROC, (HANDLE)baseWndProc);
}
}
/* Store buddy window class type */
infoPtr->BuddyType = BUDDY_TYPE_UNKNOWN;
if (GetClassNameA(bud, buddyClass, COUNT_OF(buddyClass))) {
if (lstrcmpiA(buddyClass, "Edit") == 0)
infoPtr->BuddyType = BUDDY_TYPE_EDIT;
else if (lstrcmpiA(buddyClass, "Listbox") == 0)
infoPtr->BuddyType = BUDDY_TYPE_LISTBOX;
}
/* Get the rect of the buddy relative to its parent */
GetWindowRect(infoPtr->Buddy, &budRect);
MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy), (POINT *)(&budRect.left), 2);
if(dwStyle & UDS_ARROWKEYS){
/* Note that I don't clear the BUDDY_SUPERCLASS_WNDPROC property
when we reset the upDown ctrl buddy to another buddy because it is not
good to break the window proc chain. */
if (!GetPropA(bud, BUDDY_SUPERCLASS_WNDPROC)) {
baseWndProc = (WNDPROC)SetWindowLongW(bud, GWL_WNDPROC, (LPARAM)UPDOWN_Buddy_SubclassProc);
SetPropA(bud, BUDDY_SUPERCLASS_WNDPROC, (HANDLE)baseWndProc);
}
}
/* now do the positioning */
if (dwStyle & UDS_ALIGNLEFT) {
x = budRect.left;
budRect.left += DEFAULT_WIDTH + DEFAULT_XSEP;
} else if (dwStyle & UDS_ALIGNRIGHT) {
budRect.right -= DEFAULT_WIDTH + DEFAULT_XSEP;
x = budRect.right+DEFAULT_XSEP;
/* Get the rect of the buddy relative to its parent */
GetWindowRect(infoPtr->Buddy, &budRect);
MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy), (POINT *)(&budRect.left), 2);
/* now do the positioning */
if (dwStyle & UDS_ALIGNLEFT) {
x = budRect.left;
budRect.left += DEFAULT_WIDTH + DEFAULT_XSEP;
} else if (dwStyle & UDS_ALIGNRIGHT) {
budRect.right -= DEFAULT_WIDTH + DEFAULT_XSEP;
x = budRect.right+DEFAULT_XSEP;
} else {
x = budRect.right+DEFAULT_XSEP;
}
/* first adjust the buddy to accomodate the up/down */
SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top,
budRect.right - budRect.left, budRect.bottom - budRect.top,
SWP_NOACTIVATE|SWP_NOZORDER);
/* now position the up/down */
/* Since the UDS_ALIGN* flags were used, */
/* we will pick the position and size of the window. */
width = DEFAULT_WIDTH;
/*
* 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.
*/
if (UPDOWN_HasBuddyBorder(infoPtr)) {
if(dwStyle & UDS_ALIGNLEFT)
width += DEFAULT_BUDDYBORDER;
else
x -= DEFAULT_BUDDYBORDER;
}
SetWindowPos(infoPtr->Self, infoPtr->Buddy, x,
budRect.top - DEFAULT_ADDTOP, width,
budRect.bottom - budRect.top + DEFAULT_ADDTOP + DEFAULT_ADDBOT,
SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOZORDER);
} else {
x = budRect.right+DEFAULT_XSEP;
RECT rect;
GetWindowRect(infoPtr->Self, &rect);
MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Self), (POINT *)&rect, 2);
SetWindowPos(infoPtr->Self, 0, rect.left, rect.top, DEFAULT_WIDTH, rect.bottom - rect.top,
SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOZORDER);
}
/* first adjust the buddy to accomodate the up/down */
SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top,
budRect.right - budRect.left, budRect.bottom - budRect.top,
SWP_NOACTIVATE|SWP_NOZORDER);
/* now position the up/down */
/* Since the UDS_ALIGN* flags were used, */
/* we will pick the position and size of the window. */
width = DEFAULT_WIDTH;
/*
* 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.
*/
if (UPDOWN_HasBuddyBorder(infoPtr)) {
if(dwStyle & UDS_ALIGNLEFT)
width += DEFAULT_BUDDYBORDER;
else
x -= DEFAULT_BUDDYBORDER;
}
SetWindowPos(infoPtr->Self, infoPtr->Buddy, x,
budRect.top - DEFAULT_ADDTOP, width,
budRect.bottom - budRect.top + DEFAULT_ADDTOP + DEFAULT_ADDBOT,
SWP_NOACTIVATE);
return TRUE;
return ret;
}
/***********************************************************************
@ -859,9 +870,7 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam,
return (LRESULT)infoPtr->Buddy;
case UDM_SETBUDDY:
temp = (int)infoPtr->Buddy;
UPDOWN_SetBuddy (infoPtr, (HWND)wParam);
return temp;
return (LRESULT)UPDOWN_SetBuddy (infoPtr, (HWND)wParam);
case UDM_GETPOS:
temp = UPDOWN_GetBuddyInt (infoPtr);
@ -948,7 +957,7 @@ void UPDOWN_Register(void)
WNDCLASSW wndClass;
ZeroMemory( &wndClass, sizeof( WNDCLASSW ) );
wndClass.style = CS_GLOBALCLASS | CS_VREDRAW;
wndClass.style = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
wndClass.lpfnWndProc = (WNDPROC)UpDownWindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(UPDOWN_INFO*);

View file

@ -4,7 +4,7 @@ RCS file: /home/wine/wine/dlls/comctl32/comctl32.spec,v
retrieving revision 1.43
diff -u -r1.43 comctl32.spec
--- comctl32.spec 20 Feb 2004 05:16:37 -0000 1.43
+++ comctl32.spec 14 Mar 2004 09:18:35 -0000
+++ comctl32.spec 15 Apr 2004 08:36:51 -0000
@@ -106,13 +106,13 @@
412 stdcall RemoveWindowSubclass(long ptr long)
413 stdcall DefSubclassProc(long long long long)
@ -26,13 +26,34 @@ diff -u -r1.43 comctl32.spec
# Functions imported by name
Index: imagelist.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/imagelist.c,v
retrieving revision 1.85
diff -u -r1.85 imagelist.c
--- imagelist.c 27 Feb 2004 04:40:08 -0000 1.85
+++ imagelist.c 15 Apr 2004 08:36:52 -0000
@@ -1146,11 +1146,13 @@
PatBlt(hBlendMaskDC, 0, 0, cx, cy, PATCOPY);
SelectObject(hBlendMaskDC, hOldBrush);
+#if 0
/* Modify the blend mask if an Image Mask exist */
if(himl->hbmMask) {
BitBlt(hBlendMaskDC, 0, 0, cx, cy, hMaskListDC, lx, ly, 0x220326); /* NOTSRCAND */
BitBlt(hBlendMaskDC, 0, 0, cx, cy, hBlendMaskDC, 0, 0, NOTSRCCOPY);
}
+#endif
/* now apply blend to the current image given the BlendMask */
if (clrBlend == CLR_DEFAULT) clrBlend = GetSysColor (COLOR_HIGHLIGHT);
Index: listview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/listview.c,v
retrieving revision 1.384
diff -u -r1.384 listview.c
--- listview.c 20 Feb 2004 05:12:49 -0000 1.384
+++ listview.c 14 Mar 2004 09:18:43 -0000
retrieving revision 1.385
diff -u -r1.385 listview.c
--- listview.c 11 Mar 2004 00:39:53 -0000 1.385
+++ listview.c 15 Apr 2004 08:36:56 -0000
@@ -147,6 +147,7 @@
#include <assert.h>
#include <ctype.h>
@ -41,48 +62,13 @@ diff -u -r1.384 listview.c
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
Index: rebar.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/rebar.c,v
retrieving revision 1.85
diff -u -r1.85 rebar.c
--- rebar.c 27 Feb 2004 04:32:54 -0000 1.85
+++ rebar.c 14 Mar 2004 09:18:47 -0000
@@ -985,7 +985,7 @@
}
/* text is visible */
- if (lpBand->fStatus & HAS_TEXT) {
+ if ((lpBand->fStatus & HAS_TEXT) && !(lpBand->fStyle & RBBS_HIDETITLE)) {
lpBand->fDraw |= DRAW_TEXT;
lpBand->rcCapText.right = max(lpBand->rcCapText.left,
lpBand->rcCapText.right-REBAR_POST_TEXT);
@@ -1131,7 +1131,7 @@
}
/* text is visible */
- if (lpBand->fStatus & HAS_TEXT) {
+ if ((lpBand->fStatus & HAS_TEXT) && !(lpBand->fStyle & RBBS_HIDETITLE)) {
lpBand->fDraw |= DRAW_TEXT;
lpBand->rcCapText.bottom = max(lpBand->rcCapText.top,
lpBand->rcCapText.bottom);
@@ -2027,7 +2027,8 @@
}
/* text is visible */
- if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)) {
+ if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText) &&
+ !(lpBand->fStyle & RBBS_HIDETITLE)) {
HDC hdc = GetDC (0);
HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
SIZE size;
Index: string.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/string.c,v
retrieving revision 1.3
diff -u -r1.3 string.c
--- string.c 20 Feb 2004 19:58:39 -0000 1.3
+++ string.c 14 Mar 2004 09:18:48 -0000
+++ string.c 15 Apr 2004 08:36:56 -0000
@@ -254,7 +254,7 @@
{
TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
@ -101,3 +87,19 @@ diff -u -r1.3 string.c
}
/*************************************************************************
Index: treeview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/treeview.c,v
retrieving revision 1.145
diff -u -r1.145 treeview.c
--- treeview.c 1 Mar 2004 23:10:52 -0000 1.145
+++ treeview.c 15 Apr 2004 08:36:58 -0000
@@ -3093,7 +3093,7 @@
TRACE("\n");
if (wineItem->state & TVIS_EXPANDED)
- return FALSE;
+ return TRUE;
TRACE("TVE_EXPAND %p %s\n", wineItem, TREEVIEW_ItemName(wineItem));