mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Sync to Wine-20050725:
Vitaliy Margolen <wine-patch@kievinfo.com> - Send CDDS_ITEMPOSTERASE | CDDS_PREPAINT notify. Felix Nawothnig <felix.nawothnig@t-online.de> - Move DPA and DSA functions out of comctl32undoc.c as they are documented by now. - Fix some DPA functions so they pass the new tests. - Don't invalidate the whole propsheet when the page is switched. Dimi Paun <dimi@lattica.com> - Silence uninitialized warnings. Robert Shearman <rob@codeweavers.com> - Call SetBkMode with the correct value from the NMTBCUSTOMDRAW structure. - Don't fill the NMTBCUSTOMDRAW structure in again for CDDS_POSTPAINT. - Remove redundant bBtnTransprnt value. - Height is now calculated based on the number of rows, not on the bounding rect. - Only call CalcToolbar in AutoSize if it has TBSTYLE_WRAPABLE or TBSTYLE_EX_UNDOC1 set. - Remove a bad test in SetButtonWidth that fixes a regression from the above change in IE. - Remove unnecessary nHeight data. - Remove duplicated code in Size by calling AutoSize. - Remove unnecessary bAutoSize value because SetWindowPos doesn't generate WM_SIZE when there is nothing to do on both Windows and Wine. - TBSTATE_INDETERMINATE only takes effect if the button is enabled, otherwise it should just appear like any other disabled button. - Native autosizes on inserting/adding buttons, so we should too. - The IsValidImageList test is not needed because if it isn't a valid image list we will have set the bitmap width and height to 1 and it does the wrong thing when no buttons are present. - The calculated button height should include the text height when no buttons are present. - Handle CopyImage and other functions failing by not adding the icon and notifying the caller. Thomas Weidenmueller <wine-patches@reactsoft.com> - Support PSH_WIZARDHASFINISH in wizards. - Correct tab order of the wizard buttons. - Support PSM_IDTOINDEX. Aric Stewart <aric@codeweavers.com> - When adding an image copy the full previous buffer. - Implement replacing an icon with one from a resource. Kevin Koltzau <kevin@plop.org> - Forward some header notifications to parent of listview. Frank Richter <frank.richter@gmail.com> - Enabled "tab" dialog texture for property sheet pages. - Add theming support for header controls. - Use theming for the ListView non-client area. - Let property sheets update the cached system colors upon receiving WM_SYSCOLORCHANGE. - Add theming for the up/down control. svn path=/trunk/; revision=17326
This commit is contained in:
parent
420b109b72
commit
e98f97ee9f
27 changed files with 1998 additions and 1705 deletions
|
@ -13,13 +13,16 @@
|
|||
<library>advapi32</library>
|
||||
<library>gdi32</library>
|
||||
<library>user32</library>
|
||||
<library>uxtheme</library>
|
||||
<library>winmm</library>
|
||||
<file>animate.c</file>
|
||||
<file>comboex.c</file>
|
||||
<file>comctl32undoc.c</file>
|
||||
<file>commctrl.c</file>
|
||||
<file>datetime.c</file>
|
||||
<file>dpa.c</file>
|
||||
<file>draglist.c</file>
|
||||
<file>dsa.c</file>
|
||||
<file>flatsb.c</file>
|
||||
<file>header.c</file>
|
||||
<file>hotkey.c</file>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -37,9 +37,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Wizard"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "结束", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "下一步(&N) >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< 上一步(&B)", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "下一步(&N) >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "结束", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "取消", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "帮助", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -39,9 +39,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Prùvodce"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Dokonèit", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Dal¹í >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Zpìt", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Dal¹í >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Dokonèit", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Storno", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Nápovìda", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -57,9 +57,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Wizard"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "&Beenden", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Weiter >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Zurück", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Weiter >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Beenden", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Abbrechen", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "&Hilfe", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -36,9 +36,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Wizard"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Finish", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Next >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Back", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Next >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Finish", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Cancel", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Help", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -36,9 +36,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Ayudante"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Terminar", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Siguiente >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Anterior", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Siguiente >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Terminar", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Cancelar", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Ayuda", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -40,9 +40,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Assistant"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Terminer", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Suivant >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Précédent", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Suivant >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Terminer", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Annuler", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Aide", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -37,9 +37,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Wizard"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Fine", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Avanti >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Indietro", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Avanti >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Fine", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Anulla", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Aiuto", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -36,9 +36,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Wizard"
|
||||
FONT 9, "MS UI Gothic"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Š®—¹", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "<22>i‚Þ(&N) >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< 戻る(&B)", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "<22>i‚Þ(&N) >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Š®—¹", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "キャンセル", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "ヘルプ", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -36,9 +36,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Wizard"
|
||||
FONT 9, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "종료", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "다음(&N) >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< 이전(&B)", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "다음(&N) >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "종료", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "취소", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "도움말", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -38,9 +38,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Assistent"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Beëindigen", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Volgende >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< V&orige", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Volgende >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Beëindigen", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Annuleren", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Help", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -37,9 +37,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Kreator"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Zakoñcz", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Dalej >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Wstecz", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Dalej >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Zakoñcz", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Anuluj", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Pomoc", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -36,9 +36,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Assistente"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Finalizar", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Avançar >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Voltar", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Avançar >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Finalizar", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Cancelar", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Ajuda", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -38,9 +38,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Ìàñòåð"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Çàâåðøèòü", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Äàëåå >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Íàçàä", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Äàëåå >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Çàâåðøèòü", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Îòìåíà", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "&Ñïðàâêà", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -36,9 +36,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Èarovnik"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Dokonèaj", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Naprej >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< Na&zaj", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "Naprej >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Dokonèaj", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Preklièi", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Pomoè", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -36,9 +36,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Guide"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Slutför", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Nästa >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Föregående", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Nästa >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "Slutför", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "Avbryt", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "Hjälp", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -36,9 +36,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Wizard"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "·íÒãËéàÊÃç¨", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "µèÍä» >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< Âé͹¡ÅѺ", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "µèÍä» >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "·íÒãËéàÊÃç¨", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "¡àÅÔ¡", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "ªèÇÂàËÅÕÍ", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
|
@ -38,9 +38,9 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
|
|||
CAPTION "Ìàñòåð"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "&Çàâåðøèòè", IDC_FINISH_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Äàë³ >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "< &Íàçàä", IDC_BACK_BUTTON,71,138,50,14
|
||||
DEFPUSHBUTTON "&Äàë³ >", IDC_NEXT_BUTTON,121,138,50,14
|
||||
DEFPUSHBUTTON "&Çàâåðøèòè", IDC_FINISH_BUTTON,121,138,50,14
|
||||
PUSHBUTTON "&³äì³íà", IDCANCEL,178,138,50,14
|
||||
PUSHBUTTON "&Äîâ³äêà", IDHELP,235,138,50,14,WS_GROUP
|
||||
LTEXT "", IDC_SUNKEN_LINE,7,129,278,1,SS_SUNKEN
|
||||
|
|
973
reactos/lib/comctl32/dpa.c
Normal file
973
reactos/lib/comctl32/dpa.c
Normal file
|
@ -0,0 +1,973 @@
|
|||
/*
|
||||
* Dynamic pointer array (DPA) implementation
|
||||
*
|
||||
* Copyright 1998 Eric Kohl
|
||||
* 1998 Juergen Schmied <j.schmied@metronet.de>
|
||||
* 2000 Eric Kohl for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
* These functions were involuntarily documented by Microsoft in 2002 as
|
||||
* the outcome of an anti-trust suit brought by various U.S. governments.
|
||||
* As a result the specifications on MSDN are inaccurate, incomplete
|
||||
* and misleading. A much more complete (unofficial) documentation is
|
||||
* available at:
|
||||
*
|
||||
* http://members.ozemail.com.au/~geoffch/samples/win32/shell/comctl32
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "commctrl.h"
|
||||
#include "objbase.h"
|
||||
|
||||
#include "comctl32.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dpa);
|
||||
|
||||
struct _DPA
|
||||
{
|
||||
INT nItemCount;
|
||||
LPVOID *ptrs;
|
||||
HANDLE hHeap;
|
||||
INT nGrow;
|
||||
INT nMaxCount;
|
||||
};
|
||||
|
||||
typedef struct _STREAMDATA
|
||||
{
|
||||
DWORD dwSize;
|
||||
DWORD dwData2;
|
||||
DWORD dwItems;
|
||||
} STREAMDATA, *PSTREAMDATA;
|
||||
|
||||
typedef struct _LOADDATA
|
||||
{
|
||||
INT nCount;
|
||||
PVOID ptr;
|
||||
} LOADDATA, *LPLOADDATA;
|
||||
|
||||
typedef HRESULT (CALLBACK *DPALOADPROC)(LPLOADDATA,IStream*,LPARAM);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_LoadStream [COMCTL32.9]
|
||||
*
|
||||
* Loads a dynamic pointer array from a stream
|
||||
*
|
||||
* PARAMS
|
||||
* phDpa [O] pointer to a handle to a dynamic pointer array
|
||||
* loadProc [I] pointer to a callback function
|
||||
* pStream [I] pointer to a stream
|
||||
* lParam [I] application specific value
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*
|
||||
* NOTES
|
||||
* No more information available yet!
|
||||
*/
|
||||
HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, DPALOADPROC loadProc,
|
||||
IStream *pStream, LPARAM lParam)
|
||||
{
|
||||
HRESULT errCode;
|
||||
LARGE_INTEGER position;
|
||||
ULARGE_INTEGER newPosition;
|
||||
STREAMDATA streamData;
|
||||
LOADDATA loadData;
|
||||
ULONG ulRead;
|
||||
HDPA hDpa;
|
||||
PVOID *ptr;
|
||||
|
||||
FIXME ("phDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
|
||||
phDpa, loadProc, pStream, lParam);
|
||||
|
||||
if (!phDpa || !loadProc || !pStream)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*phDpa = (HDPA)NULL;
|
||||
|
||||
position.QuadPart = 0;
|
||||
|
||||
/*
|
||||
* Zero out our streamData
|
||||
*/
|
||||
memset(&streamData,0,sizeof(STREAMDATA));
|
||||
|
||||
errCode = IStream_Seek (pStream, position, STREAM_SEEK_CUR, &newPosition);
|
||||
if (errCode != S_OK)
|
||||
return errCode;
|
||||
|
||||
errCode = IStream_Read (pStream, &streamData, sizeof(STREAMDATA), &ulRead);
|
||||
if (errCode != S_OK)
|
||||
return errCode;
|
||||
|
||||
FIXME ("dwSize=%lu dwData2=%lu dwItems=%lu\n",
|
||||
streamData.dwSize, streamData.dwData2, streamData.dwItems);
|
||||
|
||||
if ( ulRead < sizeof(STREAMDATA) ||
|
||||
lParam < sizeof(STREAMDATA) ||
|
||||
streamData.dwSize < sizeof(STREAMDATA) ||
|
||||
streamData.dwData2 < 1) {
|
||||
errCode = E_FAIL;
|
||||
}
|
||||
|
||||
if (streamData.dwItems > (UINT_MAX / 2 / sizeof(VOID*))) /* 536870911 */
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* create the dpa */
|
||||
hDpa = DPA_Create (streamData.dwItems);
|
||||
if (!hDpa)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (!DPA_Grow (hDpa, streamData.dwItems))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* load data from the stream into the dpa */
|
||||
ptr = hDpa->ptrs;
|
||||
for (loadData.nCount = 0; loadData.nCount < streamData.dwItems; loadData.nCount++) {
|
||||
errCode = (loadProc)(&loadData, pStream, lParam);
|
||||
if (errCode != S_OK) {
|
||||
errCode = S_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
*ptr = loadData.ptr;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* set the number of items */
|
||||
hDpa->nItemCount = loadData.nCount;
|
||||
|
||||
/* store the handle to the dpa */
|
||||
*phDpa = hDpa;
|
||||
FIXME ("new hDpa=%p, errorcode=%lx\n", hDpa, errCode);
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_SaveStream [COMCTL32.10]
|
||||
*
|
||||
* Saves a dynamic pointer array to a stream
|
||||
*
|
||||
* PARAMS
|
||||
* hDpa [I] handle to a dynamic pointer array
|
||||
* loadProc [I] pointer to a callback function
|
||||
* pStream [I] pointer to a stream
|
||||
* lParam [I] application specific value
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*
|
||||
* NOTES
|
||||
* No more information available yet!
|
||||
*/
|
||||
HRESULT WINAPI DPA_SaveStream (const HDPA hDpa, DPALOADPROC loadProc,
|
||||
IStream *pStream, LPARAM lParam)
|
||||
{
|
||||
|
||||
FIXME ("hDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
|
||||
hDpa, loadProc, pStream, lParam);
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_Merge [COMCTL32.11]
|
||||
*
|
||||
* Merge two dynamic pointers arrays.
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa1 [I] handle to a dynamic pointer array
|
||||
* hdpa2 [I] handle to a dynamic pointer array
|
||||
* dwFlags [I] flags
|
||||
* pfnCompare [I] pointer to sort function
|
||||
* pfnMerge [I] pointer to merge function
|
||||
* lParam [I] application specific value
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*
|
||||
* NOTES
|
||||
* No more information available yet!
|
||||
*/
|
||||
BOOL WINAPI DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
|
||||
PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge,
|
||||
LPARAM lParam)
|
||||
{
|
||||
INT nCount;
|
||||
LPVOID *pWork1, *pWork2;
|
||||
INT nResult, i;
|
||||
INT nIndex;
|
||||
|
||||
TRACE("%p %p %08lx %p %p %08lx)\n",
|
||||
hdpa1, hdpa2, dwFlags, pfnCompare, pfnMerge, lParam);
|
||||
|
||||
if (IsBadWritePtr (hdpa1, sizeof(*hdpa1)))
|
||||
return FALSE;
|
||||
|
||||
if (IsBadWritePtr (hdpa2, sizeof(*hdpa2)))
|
||||
return FALSE;
|
||||
|
||||
if (IsBadCodePtr ((FARPROC)pfnCompare))
|
||||
return FALSE;
|
||||
|
||||
if (IsBadCodePtr ((FARPROC)pfnMerge))
|
||||
return FALSE;
|
||||
|
||||
if (!(dwFlags & DPAM_NOSORT)) {
|
||||
TRACE("sorting dpa's!\n");
|
||||
if (hdpa1->nItemCount > 0)
|
||||
DPA_Sort (hdpa1, pfnCompare, lParam);
|
||||
TRACE ("dpa 1 sorted!\n");
|
||||
if (hdpa2->nItemCount > 0)
|
||||
DPA_Sort (hdpa2, pfnCompare, lParam);
|
||||
TRACE ("dpa 2 sorted!\n");
|
||||
}
|
||||
|
||||
if (hdpa2->nItemCount < 1)
|
||||
return TRUE;
|
||||
|
||||
TRACE("hdpa1->nItemCount=%d hdpa2->nItemCount=%d\n",
|
||||
hdpa1->nItemCount, hdpa2->nItemCount);
|
||||
|
||||
|
||||
/* working but untrusted implementation */
|
||||
|
||||
pWork1 = &(hdpa1->ptrs[hdpa1->nItemCount - 1]);
|
||||
pWork2 = &(hdpa2->ptrs[hdpa2->nItemCount - 1]);
|
||||
|
||||
nIndex = hdpa1->nItemCount - 1;
|
||||
nCount = hdpa2->nItemCount - 1;
|
||||
|
||||
do
|
||||
{
|
||||
if (nIndex < 0) {
|
||||
if ((nCount >= 0) && (dwFlags & DPAM_INSERT)) {
|
||||
/* Now insert the remaining new items into DPA 1 */
|
||||
TRACE("%d items to be inserted at start of DPA 1\n",
|
||||
nCount+1);
|
||||
for (i=nCount; i>=0; i--) {
|
||||
PVOID ptr;
|
||||
|
||||
ptr = (pfnMerge)(3, *pWork2, NULL, lParam);
|
||||
if (!ptr)
|
||||
return FALSE;
|
||||
DPA_InsertPtr (hdpa1, 0, ptr);
|
||||
pWork2--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
nResult = (pfnCompare)(*pWork1, *pWork2, lParam);
|
||||
TRACE("compare result=%d, dpa1.cnt=%d, dpa2.cnt=%d\n",
|
||||
nResult, nIndex, nCount);
|
||||
|
||||
if (nResult == 0)
|
||||
{
|
||||
PVOID ptr;
|
||||
|
||||
ptr = (pfnMerge)(1, *pWork1, *pWork2, lParam);
|
||||
if (!ptr)
|
||||
return FALSE;
|
||||
|
||||
nCount--;
|
||||
pWork2--;
|
||||
*pWork1 = ptr;
|
||||
nIndex--;
|
||||
pWork1--;
|
||||
}
|
||||
else if (nResult > 0)
|
||||
{
|
||||
/* item in DPA 1 missing from DPA 2 */
|
||||
if (dwFlags & DPAM_DELETE)
|
||||
{
|
||||
/* Now delete the extra item in DPA1 */
|
||||
PVOID ptr;
|
||||
|
||||
ptr = DPA_DeletePtr (hdpa1, hdpa1->nItemCount - 1);
|
||||
|
||||
(pfnMerge)(2, ptr, NULL, lParam);
|
||||
}
|
||||
nIndex--;
|
||||
pWork1--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* new item in DPA 2 */
|
||||
if (dwFlags & DPAM_INSERT)
|
||||
{
|
||||
/* Now insert the new item in DPA 1 */
|
||||
PVOID ptr;
|
||||
|
||||
ptr = (pfnMerge)(3, *pWork2, NULL, lParam);
|
||||
if (!ptr)
|
||||
return FALSE;
|
||||
DPA_InsertPtr (hdpa1, nIndex+1, ptr);
|
||||
}
|
||||
nCount--;
|
||||
pWork2--;
|
||||
}
|
||||
|
||||
}
|
||||
while (nCount >= 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_Destroy [COMCTL32.329]
|
||||
*
|
||||
* Destroys a dynamic pointer array
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the pointer array
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DPA_Destroy (const HDPA hdpa)
|
||||
{
|
||||
TRACE("(%p)\n", hdpa);
|
||||
|
||||
if (!hdpa)
|
||||
return FALSE;
|
||||
|
||||
if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
|
||||
return FALSE;
|
||||
|
||||
return HeapFree (hdpa->hHeap, 0, hdpa);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_Grow [COMCTL32.330]
|
||||
*
|
||||
* Sets the growth amount.
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the existing (source) pointer array
|
||||
* nGrow [I] number of items by which the array grows when it's too small
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DPA_Grow (const HDPA hdpa, INT nGrow)
|
||||
{
|
||||
TRACE("(%p %d)\n", hdpa, nGrow);
|
||||
|
||||
if (!hdpa)
|
||||
return FALSE;
|
||||
|
||||
hdpa->nGrow = max(8, nGrow);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_Clone [COMCTL32.331]
|
||||
*
|
||||
* Copies a pointer array to an other one or creates a copy
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the existing (source) pointer array
|
||||
* hdpaNew [O] handle (pointer) to the destination pointer array
|
||||
*
|
||||
* RETURNS
|
||||
* Success: pointer to the destination pointer array.
|
||||
* Failure: NULL
|
||||
*
|
||||
* NOTES
|
||||
* - If the 'hdpaNew' is a NULL-Pointer, a copy of the source pointer
|
||||
* array will be created and it's handle (pointer) is returned.
|
||||
* - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
|
||||
* this implementation just returns NULL.
|
||||
*/
|
||||
HDPA WINAPI DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
|
||||
{
|
||||
INT nNewItems, nSize;
|
||||
HDPA hdpaTemp;
|
||||
|
||||
if (!hdpa)
|
||||
return NULL;
|
||||
|
||||
TRACE("(%p %p)\n", hdpa, hdpaNew);
|
||||
|
||||
if (!hdpaNew) {
|
||||
/* create a new DPA */
|
||||
hdpaTemp = HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
|
||||
sizeof(*hdpaTemp));
|
||||
hdpaTemp->hHeap = hdpa->hHeap;
|
||||
hdpaTemp->nGrow = hdpa->nGrow;
|
||||
}
|
||||
else
|
||||
hdpaTemp = hdpaNew;
|
||||
|
||||
if (hdpaTemp->ptrs) {
|
||||
/* remove old pointer array */
|
||||
HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs);
|
||||
hdpaTemp->ptrs = NULL;
|
||||
hdpaTemp->nItemCount = 0;
|
||||
hdpaTemp->nMaxCount = 0;
|
||||
}
|
||||
|
||||
/* create a new pointer array */
|
||||
nNewItems = hdpaTemp->nGrow *
|
||||
((INT)((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1);
|
||||
nSize = nNewItems * sizeof(LPVOID);
|
||||
hdpaTemp->ptrs = HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize);
|
||||
hdpaTemp->nMaxCount = nNewItems;
|
||||
|
||||
/* clone the pointer array */
|
||||
hdpaTemp->nItemCount = hdpa->nItemCount;
|
||||
memmove (hdpaTemp->ptrs, hdpa->ptrs,
|
||||
hdpaTemp->nItemCount * sizeof(LPVOID));
|
||||
|
||||
return hdpaTemp;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_GetPtr [COMCTL32.332]
|
||||
*
|
||||
* Retrieves a pointer from a dynamic pointer array
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the pointer array
|
||||
* nIndex [I] array index of the desired pointer
|
||||
*
|
||||
* RETURNS
|
||||
* Success: pointer
|
||||
* Failure: NULL
|
||||
*/
|
||||
LPVOID WINAPI DPA_GetPtr (const HDPA hdpa, INT nIndex)
|
||||
{
|
||||
TRACE("(%p %d)\n", hdpa, nIndex);
|
||||
|
||||
if (!hdpa)
|
||||
return NULL;
|
||||
if (!hdpa->ptrs) {
|
||||
WARN("no pointer array.\n");
|
||||
return NULL;
|
||||
}
|
||||
if ((nIndex < 0) || (nIndex >= hdpa->nItemCount)) {
|
||||
WARN("not enough pointers in array (%d vs %d).\n",nIndex,hdpa->nItemCount);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("-- %p\n", hdpa->ptrs[nIndex]);
|
||||
|
||||
return hdpa->ptrs[nIndex];
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_GetPtrIndex [COMCTL32.333]
|
||||
*
|
||||
* Retrieves the index of the specified pointer
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the pointer array
|
||||
* p [I] pointer
|
||||
*
|
||||
* RETURNS
|
||||
* Success: index of the specified pointer
|
||||
* Failure: -1
|
||||
*/
|
||||
INT WINAPI DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
|
||||
{
|
||||
INT i;
|
||||
|
||||
if (!hdpa || !hdpa->ptrs)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < hdpa->nItemCount; i++) {
|
||||
if (hdpa->ptrs[i] == p)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_InsertPtr [COMCTL32.334]
|
||||
*
|
||||
* Inserts a pointer into a dynamic pointer array
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the array
|
||||
* i [I] array index
|
||||
* p [I] pointer to insert
|
||||
*
|
||||
* RETURNS
|
||||
* Success: index of the inserted pointer
|
||||
* Failure: -1
|
||||
*/
|
||||
INT WINAPI DPA_InsertPtr (const HDPA hdpa, INT i, LPVOID p)
|
||||
{
|
||||
TRACE("(%p %d %p)\n", hdpa, i, p);
|
||||
|
||||
if (!hdpa || i < 0) return -1;
|
||||
|
||||
/* append item if index is out of bounds */
|
||||
i = min(hdpa->nItemCount, i);
|
||||
|
||||
/* create empty spot at the end */
|
||||
if (!DPA_SetPtr(hdpa, hdpa->nItemCount, 0)) return -1;
|
||||
|
||||
if (i != hdpa->nItemCount - 1)
|
||||
memmove (hdpa->ptrs + i + 1, hdpa->ptrs + i,
|
||||
(hdpa->nItemCount - i - 1) * sizeof(LPVOID));
|
||||
|
||||
hdpa->ptrs[i] = p;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_SetPtr [COMCTL32.335]
|
||||
*
|
||||
* Sets a pointer in the pointer array
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the pointer array
|
||||
* i [I] index of the pointer that will be set
|
||||
* p [I] pointer to be set
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DPA_SetPtr (const HDPA hdpa, INT i, LPVOID p)
|
||||
{
|
||||
LPVOID *lpTemp;
|
||||
|
||||
TRACE("(%p %d %p)\n", hdpa, i, p);
|
||||
|
||||
if (!hdpa || i < 0)
|
||||
return FALSE;
|
||||
|
||||
if (hdpa->nItemCount <= i) {
|
||||
/* within the old array */
|
||||
if (hdpa->nMaxCount <= i) {
|
||||
/* resize the block of memory */
|
||||
INT nNewItems =
|
||||
hdpa->nGrow * ((INT)(((i+1) - 1) / hdpa->nGrow) + 1);
|
||||
INT nSize = nNewItems * sizeof(LPVOID);
|
||||
|
||||
if (hdpa->ptrs)
|
||||
lpTemp = HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, hdpa->ptrs, nSize);
|
||||
else
|
||||
lpTemp = HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY, nSize);
|
||||
|
||||
if (!lpTemp)
|
||||
return FALSE;
|
||||
|
||||
hdpa->nMaxCount = nNewItems;
|
||||
hdpa->ptrs = lpTemp;
|
||||
}
|
||||
hdpa->nItemCount = i+1;
|
||||
}
|
||||
|
||||
/* put the new entry in */
|
||||
hdpa->ptrs[i] = p;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_DeletePtr [COMCTL32.336]
|
||||
*
|
||||
* Removes a pointer from the pointer array.
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the pointer array
|
||||
* i [I] index of the pointer that will be deleted
|
||||
*
|
||||
* RETURNS
|
||||
* Success: deleted pointer
|
||||
* Failure: NULL
|
||||
*/
|
||||
LPVOID WINAPI DPA_DeletePtr (const HDPA hdpa, INT i)
|
||||
{
|
||||
LPVOID *lpDest, *lpSrc, lpTemp = NULL;
|
||||
INT nSize;
|
||||
|
||||
TRACE("(%p %d)\n", hdpa, i);
|
||||
|
||||
if ((!hdpa) || i < 0 || i >= hdpa->nItemCount)
|
||||
return NULL;
|
||||
|
||||
lpTemp = hdpa->ptrs[i];
|
||||
|
||||
/* do we need to move ?*/
|
||||
if (i < hdpa->nItemCount - 1) {
|
||||
lpDest = hdpa->ptrs + i;
|
||||
lpSrc = lpDest + 1;
|
||||
nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID);
|
||||
TRACE("-- move dest=%p src=%p size=%x\n",
|
||||
lpDest, lpSrc, nSize);
|
||||
memmove (lpDest, lpSrc, nSize);
|
||||
}
|
||||
|
||||
hdpa->nItemCount --;
|
||||
|
||||
/* free memory ?*/
|
||||
if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) {
|
||||
INT nNewItems = max(hdpa->nGrow * 2, hdpa->nItemCount);
|
||||
nSize = nNewItems * sizeof(LPVOID);
|
||||
lpDest = HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
|
||||
hdpa->ptrs, nSize);
|
||||
if (!lpDest)
|
||||
return NULL;
|
||||
|
||||
hdpa->nMaxCount = nNewItems;
|
||||
hdpa->ptrs = (LPVOID*)lpDest;
|
||||
}
|
||||
|
||||
return lpTemp;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_DeleteAllPtrs [COMCTL32.337]
|
||||
*
|
||||
* Removes all pointers and reinitializes the array.
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the pointer array
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DPA_DeleteAllPtrs (const HDPA hdpa)
|
||||
{
|
||||
TRACE("(%p)\n", hdpa);
|
||||
|
||||
if (!hdpa)
|
||||
return FALSE;
|
||||
|
||||
if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
|
||||
return FALSE;
|
||||
|
||||
hdpa->nItemCount = 0;
|
||||
hdpa->nMaxCount = hdpa->nGrow * 2;
|
||||
hdpa->ptrs = HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
|
||||
hdpa->nMaxCount * sizeof(LPVOID));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_QuickSort [Internal]
|
||||
*
|
||||
* Ordinary quicksort (used by DPA_Sort).
|
||||
*
|
||||
* PARAMS
|
||||
* lpPtrs [I] pointer to the pointer array
|
||||
* l [I] index of the "left border" of the partition
|
||||
* r [I] index of the "right border" of the partition
|
||||
* pfnCompare [I] pointer to the compare function
|
||||
* lParam [I] user defined value (3rd parameter in compare function)
|
||||
*
|
||||
* RETURNS
|
||||
* NONE
|
||||
*/
|
||||
static VOID DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
|
||||
PFNDPACOMPARE pfnCompare, LPARAM lParam)
|
||||
{
|
||||
INT m;
|
||||
LPVOID t;
|
||||
|
||||
TRACE("l=%i r=%i\n", l, r);
|
||||
|
||||
if (l==r) /* one element is always sorted */
|
||||
return;
|
||||
if (r<l) /* oops, got it in the wrong order */
|
||||
{
|
||||
DPA_QuickSort(lpPtrs, r, l, pfnCompare, lParam);
|
||||
return;
|
||||
}
|
||||
m = (l+r)/2; /* divide by two */
|
||||
DPA_QuickSort(lpPtrs, l, m, pfnCompare, lParam);
|
||||
DPA_QuickSort(lpPtrs, m+1, r, pfnCompare, lParam);
|
||||
|
||||
/* join the two sides */
|
||||
while( (l<=m) && (m<r) )
|
||||
{
|
||||
if(pfnCompare(lpPtrs[l],lpPtrs[m+1],lParam)>0)
|
||||
{
|
||||
t = lpPtrs[m+1];
|
||||
memmove(&lpPtrs[l+1],&lpPtrs[l],(m-l+1)*sizeof(lpPtrs[l]));
|
||||
lpPtrs[l] = t;
|
||||
|
||||
m++;
|
||||
}
|
||||
l++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_Sort [COMCTL32.338]
|
||||
*
|
||||
* Sorts a pointer array using a user defined compare function
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the pointer array
|
||||
* pfnCompare [I] pointer to the compare function
|
||||
* lParam [I] user defined value (3rd parameter of compare function)
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
|
||||
{
|
||||
if (!hdpa || !pfnCompare)
|
||||
return FALSE;
|
||||
|
||||
TRACE("(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);
|
||||
|
||||
if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
|
||||
DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
|
||||
pfnCompare, lParam);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_Search [COMCTL32.339]
|
||||
*
|
||||
* Searches a pointer array for a specified pointer
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle (pointer) to the pointer array
|
||||
* pFind [I] pointer to search for
|
||||
* nStart [I] start index
|
||||
* pfnCompare [I] pointer to the compare function
|
||||
* lParam [I] user defined value (3rd parameter of compare function)
|
||||
* uOptions [I] search options
|
||||
*
|
||||
* RETURNS
|
||||
* Success: index of the pointer in the array.
|
||||
* Failure: -1
|
||||
*
|
||||
* NOTES
|
||||
* Binary search taken from R.Sedgewick "Algorithms in C"!
|
||||
* Function is NOT tested!
|
||||
* If something goes wrong, blame HIM not ME! (Eric Kohl)
|
||||
*/
|
||||
INT WINAPI DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
|
||||
PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
|
||||
{
|
||||
if (!hdpa || !pfnCompare || !pFind)
|
||||
return -1;
|
||||
|
||||
TRACE("(%p %p %d %p 0x%08lx 0x%08x)\n",
|
||||
hdpa, pFind, nStart, pfnCompare, lParam, uOptions);
|
||||
|
||||
if (uOptions & DPAS_SORTED) {
|
||||
/* array is sorted --> use binary search */
|
||||
INT l, r, x, n;
|
||||
LPVOID *lpPtr;
|
||||
|
||||
TRACE("binary search\n");
|
||||
|
||||
l = (nStart == -1) ? 0 : nStart;
|
||||
r = hdpa->nItemCount - 1;
|
||||
lpPtr = hdpa->ptrs;
|
||||
while (r >= l) {
|
||||
x = (l + r) / 2;
|
||||
n = (pfnCompare)(pFind, lpPtr[x], lParam);
|
||||
if (n < 0)
|
||||
r = x - 1;
|
||||
else
|
||||
l = x + 1;
|
||||
if (n == 0) {
|
||||
TRACE("-- ret=%d\n", n);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
if (uOptions & (DPAS_INSERTBEFORE | DPAS_INSERTAFTER)) {
|
||||
TRACE("-- ret=%d\n", l);
|
||||
return l;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* array is not sorted --> use linear search */
|
||||
LPVOID *lpPtr;
|
||||
INT nIndex;
|
||||
|
||||
TRACE("linear search\n");
|
||||
|
||||
nIndex = (nStart == -1)? 0 : nStart;
|
||||
lpPtr = hdpa->ptrs;
|
||||
for (; nIndex < hdpa->nItemCount; nIndex++) {
|
||||
if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) {
|
||||
TRACE("-- ret=%d\n", nIndex);
|
||||
return nIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("-- not found: ret=-1\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_CreateEx [COMCTL32.340]
|
||||
*
|
||||
* Creates a dynamic pointer array using the specified size and heap.
|
||||
*
|
||||
* PARAMS
|
||||
* nGrow [I] number of items by which the array grows when it is filled
|
||||
* hHeap [I] handle to the heap where the array is stored
|
||||
*
|
||||
* RETURNS
|
||||
* Success: handle (pointer) to the pointer array.
|
||||
* Failure: NULL
|
||||
*
|
||||
* NOTES
|
||||
* The DPA_ functions can be used to create and manipulate arrays of
|
||||
* pointers.
|
||||
*/
|
||||
HDPA WINAPI DPA_CreateEx (INT nGrow, HANDLE hHeap)
|
||||
{
|
||||
HDPA hdpa;
|
||||
|
||||
TRACE("(%d %p)\n", nGrow, hHeap);
|
||||
|
||||
if (hHeap)
|
||||
hdpa = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(*hdpa));
|
||||
else
|
||||
hdpa = Alloc (sizeof(*hdpa));
|
||||
|
||||
if (hdpa) {
|
||||
hdpa->nGrow = max(8, nGrow);
|
||||
hdpa->hHeap = hHeap ? hHeap : GetProcessHeap();
|
||||
hdpa->nMaxCount = hdpa->nGrow * 2;
|
||||
hdpa->ptrs = HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
|
||||
hdpa->nMaxCount * sizeof(LPVOID));
|
||||
}
|
||||
|
||||
TRACE("-- %p\n", hdpa);
|
||||
|
||||
return hdpa;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_Create [COMCTL32.328]
|
||||
*
|
||||
* Creates a dynamic pointer array.
|
||||
*
|
||||
* PARAMS
|
||||
* nGrow [I] number of items by which the array grows when it is filled
|
||||
*
|
||||
* RETURNS
|
||||
* Success: handle (pointer) to the pointer array.
|
||||
* Failure: NULL
|
||||
*
|
||||
* NOTES
|
||||
* The DPA_ functions can be used to create and manipulate arrays of
|
||||
* pointers.
|
||||
*/
|
||||
HDPA WINAPI DPA_Create (INT nGrow)
|
||||
{
|
||||
return DPA_CreateEx( nGrow, 0 );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_EnumCallback [COMCTL32.385]
|
||||
*
|
||||
* Enumerates all items in a dynamic pointer array.
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle to the dynamic pointer array
|
||||
* enumProc [I]
|
||||
* lParam [I]
|
||||
*
|
||||
* RETURNS
|
||||
* none
|
||||
*/
|
||||
VOID WINAPI DPA_EnumCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc,
|
||||
LPVOID lParam)
|
||||
{
|
||||
INT i;
|
||||
|
||||
TRACE("(%p %p %p)\n", hdpa, enumProc, lParam);
|
||||
|
||||
if (!hdpa)
|
||||
return;
|
||||
if (hdpa->nItemCount <= 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < hdpa->nItemCount; i++) {
|
||||
if ((enumProc)(hdpa->ptrs[i], lParam) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_DestroyCallback [COMCTL32.386]
|
||||
*
|
||||
* Enumerates all items in a dynamic pointer array and destroys it.
|
||||
*
|
||||
* PARAMS
|
||||
* hdpa [I] handle to the dynamic pointer array
|
||||
* enumProc [I]
|
||||
* lParam [I]
|
||||
*
|
||||
* RETURNS
|
||||
* none
|
||||
*/
|
||||
void WINAPI DPA_DestroyCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc,
|
||||
LPVOID lParam)
|
||||
{
|
||||
TRACE("(%p %p %p)\n", hdpa, enumProc, lParam);
|
||||
|
||||
DPA_EnumCallback (hdpa, enumProc, lParam);
|
||||
DPA_Destroy (hdpa);
|
||||
}
|
436
reactos/lib/comctl32/dsa.c
Normal file
436
reactos/lib/comctl32/dsa.c
Normal file
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* Dynamic structure array (DSA) implementation
|
||||
*
|
||||
* Copyright 1998 Eric Kohl
|
||||
* 1998 Juergen Schmied <j.schmied@metronet.de>
|
||||
* 2000 Eric Kohl for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
* These functions were involuntarily documented by Microsoft in 2002 as
|
||||
* the outcome of an anti-trust suit brought by various U.S. governments.
|
||||
* As a result the specifications on MSDN are inaccurate, incomplete
|
||||
* and misleading. A much more complete (unofficial) documentation is
|
||||
* available at:
|
||||
*
|
||||
* http://members.ozemail.com.au/~geoffch/samples/win32/shell/comctl32
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "commctrl.h"
|
||||
|
||||
#include "comctl32.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dsa);
|
||||
|
||||
struct _DSA
|
||||
{
|
||||
INT nItemCount;
|
||||
LPVOID pData;
|
||||
INT nMaxCount;
|
||||
INT nItemSize;
|
||||
INT nGrow;
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_Create [COMCTL32.320]
|
||||
*
|
||||
* Creates a dynamic storage array
|
||||
*
|
||||
* PARAMS
|
||||
* nSize [I] size of the array elements
|
||||
* nGrow [I] number of elements by which the array grows when it is filled
|
||||
*
|
||||
* RETURNS
|
||||
* Success: pointer to an array control structure. Use this like a handle.
|
||||
* Failure: NULL
|
||||
*
|
||||
* NOTES
|
||||
* The DSA_ functions can be used to create and manipulate arrays of
|
||||
* fixed-size memory blocks. These arrays can store any kind of data
|
||||
* (e.g. strings and icons).
|
||||
*/
|
||||
HDSA WINAPI DSA_Create (INT nSize, INT nGrow)
|
||||
{
|
||||
HDSA hdsa;
|
||||
|
||||
TRACE("(size=%d grow=%d)\n", nSize, nGrow);
|
||||
|
||||
hdsa = Alloc (sizeof(*hdsa));
|
||||
if (hdsa)
|
||||
{
|
||||
hdsa->nItemCount = 0;
|
||||
hdsa->pData = NULL;
|
||||
hdsa->nMaxCount = 0;
|
||||
hdsa->nItemSize = nSize;
|
||||
hdsa->nGrow = max(1, nGrow);
|
||||
}
|
||||
|
||||
return hdsa;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_Destroy [COMCTL32.321]
|
||||
*
|
||||
* Destroys a dynamic storage array
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] pointer to the array control structure
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DSA_Destroy (const HDSA hdsa)
|
||||
{
|
||||
TRACE("(%p)\n", hdsa);
|
||||
|
||||
if (!hdsa)
|
||||
return FALSE;
|
||||
|
||||
if (hdsa->pData && (!Free (hdsa->pData)))
|
||||
return FALSE;
|
||||
|
||||
return Free (hdsa);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_GetItem [COMCTL32.322]
|
||||
*
|
||||
* Copies the specified item into a caller-supplied buffer.
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] pointer to the array control structure
|
||||
* nIndex [I] number of the Item to get
|
||||
* pDest [O] destination buffer. Has to be >= dwElementSize.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest)
|
||||
{
|
||||
LPVOID pSrc;
|
||||
|
||||
TRACE("(%p %d %p)\n", hdsa, nIndex, pDest);
|
||||
|
||||
if (!hdsa)
|
||||
return FALSE;
|
||||
if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
|
||||
return FALSE;
|
||||
|
||||
pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
|
||||
memmove (pDest, pSrc, hdsa->nItemSize);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_GetItemPtr [COMCTL32.323]
|
||||
*
|
||||
* Retrieves a pointer to the specified item.
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] pointer to the array control structure
|
||||
* nIndex [I] index of the desired item
|
||||
*
|
||||
* RETURNS
|
||||
* Success: pointer to an item
|
||||
* Failure: NULL
|
||||
*/
|
||||
LPVOID WINAPI DSA_GetItemPtr (const HDSA hdsa, INT nIndex)
|
||||
{
|
||||
LPVOID pSrc;
|
||||
|
||||
TRACE("(%p %d)\n", hdsa, nIndex);
|
||||
|
||||
if (!hdsa)
|
||||
return NULL;
|
||||
if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
|
||||
return NULL;
|
||||
|
||||
pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
|
||||
|
||||
TRACE("-- ret=%p\n", pSrc);
|
||||
|
||||
return pSrc;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_SetItem [COMCTL32.325]
|
||||
*
|
||||
* Sets the contents of an item in the array.
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] pointer to the array control structure
|
||||
* nIndex [I] index for the item
|
||||
* pSrc [I] pointer to the new item data
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
|
||||
{
|
||||
INT nSize, nNewItems;
|
||||
LPVOID pDest, lpTemp;
|
||||
|
||||
TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);
|
||||
|
||||
if ((!hdsa) || nIndex < 0)
|
||||
return FALSE;
|
||||
|
||||
if (hdsa->nItemCount <= nIndex) {
|
||||
/* within the old array */
|
||||
if (hdsa->nMaxCount > nIndex) {
|
||||
/* within the allocated space, set a new boundary */
|
||||
hdsa->nItemCount = nIndex + 1;
|
||||
}
|
||||
else {
|
||||
/* resize the block of memory */
|
||||
nNewItems =
|
||||
hdsa->nGrow * ((INT)(((nIndex + 1) - 1) / hdsa->nGrow) + 1);
|
||||
nSize = hdsa->nItemSize * nNewItems;
|
||||
|
||||
lpTemp = ReAlloc (hdsa->pData, nSize);
|
||||
if (!lpTemp)
|
||||
return FALSE;
|
||||
|
||||
hdsa->nMaxCount = nNewItems;
|
||||
hdsa->nItemCount = nIndex + 1;
|
||||
hdsa->pData = lpTemp;
|
||||
}
|
||||
}
|
||||
|
||||
/* put the new entry in */
|
||||
pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
|
||||
TRACE("-- move dest=%p src=%p size=%d\n",
|
||||
pDest, pSrc, hdsa->nItemSize);
|
||||
memmove (pDest, pSrc, hdsa->nItemSize);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_InsertItem [COMCTL32.324]
|
||||
*
|
||||
* Inserts an item into the array at the specified index.
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] pointer to the array control structure
|
||||
* nIndex [I] index for the new item
|
||||
* pSrc [I] pointer to the element
|
||||
*
|
||||
* RETURNS
|
||||
* Success: position of the new item
|
||||
* Failure: -1
|
||||
*/
|
||||
INT WINAPI DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
|
||||
{
|
||||
INT nNewItems, nSize;
|
||||
LPVOID lpTemp, lpDest;
|
||||
|
||||
TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);
|
||||
|
||||
if ((!hdsa) || nIndex < 0)
|
||||
return -1;
|
||||
|
||||
/* when nIndex >= nItemCount then append */
|
||||
if (nIndex >= hdsa->nItemCount)
|
||||
nIndex = hdsa->nItemCount;
|
||||
|
||||
/* do we need to resize ? */
|
||||
if (hdsa->nItemCount >= hdsa->nMaxCount) {
|
||||
nNewItems = hdsa->nMaxCount + hdsa->nGrow;
|
||||
nSize = hdsa->nItemSize * nNewItems;
|
||||
|
||||
lpTemp = ReAlloc (hdsa->pData, nSize);
|
||||
if (!lpTemp)
|
||||
return -1;
|
||||
|
||||
hdsa->nMaxCount = nNewItems;
|
||||
hdsa->pData = lpTemp;
|
||||
}
|
||||
|
||||
/* do we need to move elements ? */
|
||||
if (nIndex < hdsa->nItemCount) {
|
||||
lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
|
||||
lpDest = (char *) lpTemp + hdsa->nItemSize;
|
||||
nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
|
||||
TRACE("-- move dest=%p src=%p size=%d\n",
|
||||
lpDest, lpTemp, nSize);
|
||||
memmove (lpDest, lpTemp, nSize);
|
||||
}
|
||||
|
||||
/* ok, we can put the new Item in */
|
||||
hdsa->nItemCount++;
|
||||
lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
|
||||
TRACE("-- move dest=%p src=%p size=%d\n",
|
||||
lpDest, pSrc, hdsa->nItemSize);
|
||||
memmove (lpDest, pSrc, hdsa->nItemSize);
|
||||
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_DeleteItem [COMCTL32.326]
|
||||
*
|
||||
* Deletes the specified item from the array.
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] pointer to the array control structure
|
||||
* nIndex [I] index for the element to delete
|
||||
*
|
||||
* RETURNS
|
||||
* Success: number of the deleted element
|
||||
* Failure: -1
|
||||
*/
|
||||
INT WINAPI DSA_DeleteItem (const HDSA hdsa, INT nIndex)
|
||||
{
|
||||
LPVOID lpDest,lpSrc;
|
||||
INT nSize;
|
||||
|
||||
TRACE("(%p %d)\n", hdsa, nIndex);
|
||||
|
||||
if (!hdsa)
|
||||
return -1;
|
||||
if (nIndex < 0 || nIndex >= hdsa->nItemCount)
|
||||
return -1;
|
||||
|
||||
/* do we need to move ? */
|
||||
if (nIndex < hdsa->nItemCount - 1) {
|
||||
lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
|
||||
lpSrc = (char *) lpDest + hdsa->nItemSize;
|
||||
nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
|
||||
TRACE("-- move dest=%p src=%p size=%d\n",
|
||||
lpDest, lpSrc, nSize);
|
||||
memmove (lpDest, lpSrc, nSize);
|
||||
}
|
||||
|
||||
hdsa->nItemCount--;
|
||||
|
||||
/* free memory ? */
|
||||
if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
|
||||
nSize = hdsa->nItemSize * hdsa->nItemCount;
|
||||
|
||||
lpDest = ReAlloc (hdsa->pData, nSize);
|
||||
if (!lpDest)
|
||||
return -1;
|
||||
|
||||
hdsa->nMaxCount = hdsa->nItemCount;
|
||||
hdsa->pData = lpDest;
|
||||
}
|
||||
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_DeleteAllItems [COMCTL32.327]
|
||||
*
|
||||
* Removes all items and reinitializes the array.
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] pointer to the array control structure
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
* Failure: FALSE
|
||||
*/
|
||||
BOOL WINAPI DSA_DeleteAllItems (const HDSA hdsa)
|
||||
{
|
||||
TRACE("(%p)\n", hdsa);
|
||||
|
||||
if (!hdsa)
|
||||
return FALSE;
|
||||
if (hdsa->pData && (!Free (hdsa->pData)))
|
||||
return FALSE;
|
||||
|
||||
hdsa->nItemCount = 0;
|
||||
hdsa->pData = NULL;
|
||||
hdsa->nMaxCount = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_EnumCallback [COMCTL32.387]
|
||||
*
|
||||
* Enumerates all items in a dynamic storage array.
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] handle to the dynamic storage array
|
||||
* enumProc [I]
|
||||
* lParam [I]
|
||||
*
|
||||
* RETURNS
|
||||
* none
|
||||
*/
|
||||
VOID WINAPI DSA_EnumCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
|
||||
LPVOID lParam)
|
||||
{
|
||||
INT i;
|
||||
|
||||
TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);
|
||||
|
||||
if (!hdsa)
|
||||
return;
|
||||
if (hdsa->nItemCount <= 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < hdsa->nItemCount; i++) {
|
||||
LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
|
||||
if ((enumProc)(lpItem, lParam) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* DSA_DestroyCallback [COMCTL32.388]
|
||||
*
|
||||
* Enumerates all items in a dynamic storage array and destroys it.
|
||||
*
|
||||
* PARAMS
|
||||
* hdsa [I] handle to the dynamic storage array
|
||||
* enumProc [I]
|
||||
* lParam [I]
|
||||
*
|
||||
* RETURNS
|
||||
* none
|
||||
*/
|
||||
void WINAPI DSA_DestroyCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
|
||||
LPVOID lParam)
|
||||
{
|
||||
TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);
|
||||
|
||||
DSA_EnumCallback (hdsa, enumProc, lParam);
|
||||
DSA_Destroy (hdsa);
|
||||
}
|
|
@ -43,6 +43,8 @@
|
|||
#include "commctrl.h"
|
||||
#include "comctl32.h"
|
||||
#include "imagelist.h"
|
||||
#include "tmschema.h"
|
||||
#include "uxtheme.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(header);
|
||||
|
@ -94,6 +96,8 @@ typedef struct
|
|||
|
||||
#define HEADER_GetInfoPtr(hwnd) ((HEADER_INFO *)GetWindowLongPtrW(hwnd,0))
|
||||
|
||||
static const WCHAR themeClass[] = {'H','e','a','d','e','r',0};
|
||||
|
||||
|
||||
inline static LRESULT
|
||||
HEADER_IndexToOrder (HWND hwnd, INT iItem)
|
||||
|
@ -164,6 +168,7 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack)
|
|||
HEADER_ITEM *phdi = &infoPtr->items[iItem];
|
||||
RECT r;
|
||||
INT oldBkMode, cxEdge = GetSystemMetrics(SM_CXEDGE);
|
||||
HTHEME theme = GetWindowTheme (hwnd);
|
||||
|
||||
TRACE("DrawItem(iItem %d bHotTrack %d unicode flag %d)\n", iItem, bHotTrack, infoPtr->bUnicode);
|
||||
|
||||
|
@ -174,25 +179,52 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack)
|
|||
if (r.right - r.left == 0)
|
||||
return phdi->rect.right;
|
||||
|
||||
if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS) {
|
||||
if (phdi->bDown) {
|
||||
DrawEdge (hdc, &r, BDR_RAISEDOUTER,
|
||||
BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
|
||||
r.left += 2;
|
||||
r.top += 2;
|
||||
}
|
||||
else
|
||||
DrawEdge (hdc, &r, EDGE_RAISED,
|
||||
BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
|
||||
if (theme != NULL) {
|
||||
int state = (phdi->bDown) ? HIS_PRESSED :
|
||||
(bHotTrack ? HIS_HOT : HIS_NORMAL);
|
||||
DrawThemeBackground (theme, hdc, HP_HEADERITEM, state,
|
||||
&r, NULL);
|
||||
GetThemeBackgroundContentRect (theme, hdc, HP_HEADERITEM, state,
|
||||
&r, &r);
|
||||
}
|
||||
else {
|
||||
if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS) {
|
||||
if (phdi->bDown) {
|
||||
DrawEdge (hdc, &r, BDR_RAISEDOUTER,
|
||||
BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
|
||||
}
|
||||
else
|
||||
DrawEdge (hdc, &r, EDGE_RAISED,
|
||||
BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
|
||||
}
|
||||
else
|
||||
DrawEdge (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
|
||||
}
|
||||
if (phdi->bDown) {
|
||||
r.left += 2;
|
||||
r.top += 2;
|
||||
}
|
||||
else
|
||||
DrawEdge (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
|
||||
|
||||
r.left -= cxEdge;
|
||||
r.right += cxEdge;
|
||||
|
||||
if (phdi->fmt & HDF_OWNERDRAW) {
|
||||
DRAWITEMSTRUCT dis;
|
||||
NMCUSTOMDRAW nmcd;
|
||||
|
||||
nmcd.hdr.hwndFrom = hwnd;
|
||||
nmcd.hdr.idFrom = GetWindowLongPtrW (hwnd, GWLP_ID);
|
||||
nmcd.hdr.code = NM_CUSTOMDRAW;
|
||||
nmcd.dwDrawStage = CDDS_PREPAINT | CDDS_ITEM | CDDS_ITEMPOSTERASE;
|
||||
nmcd.hdc = hdc;
|
||||
nmcd.dwItemSpec = iItem;
|
||||
nmcd.rc = r;
|
||||
nmcd.uItemState = phdi->bDown ? CDIS_SELECTED : 0;
|
||||
nmcd.lItemlParam = phdi->lParam;
|
||||
|
||||
SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
|
||||
(WPARAM)nmcd.hdr.idFrom, (LPARAM)&nmcd);
|
||||
|
||||
dis.CtlType = ODT_HEADER;
|
||||
dis.CtlID = GetWindowLongPtrW (hwnd, GWLP_ID);
|
||||
dis.itemID = iItem;
|
||||
|
@ -315,7 +347,7 @@ HEADER_DrawItem (HWND hwnd, HDC hdc, INT iItem, BOOL bHotTrack)
|
|||
HDF_BITMAP_ON_RIGHT|HDF_IMAGE)))) /* no explicit format specified? */
|
||||
&& (phdi->pszText)) {
|
||||
oldBkMode = SetBkMode(hdc, TRANSPARENT);
|
||||
SetTextColor (hdc, (bHotTrack) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
|
||||
SetTextColor (hdc, (bHotTrack && !theme) ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
|
||||
r.left = tx;
|
||||
r.right = tx + tw;
|
||||
DrawTextW (hdc, phdi->pszText, -1,
|
||||
|
@ -338,6 +370,7 @@ HEADER_Refresh (HWND hwnd, HDC hdc)
|
|||
HBRUSH hbrBk;
|
||||
UINT i;
|
||||
INT x;
|
||||
HTHEME theme = GetWindowTheme (hwnd);
|
||||
|
||||
/* get rect for the bar, adjusted for the border */
|
||||
GetClientRect (hwnd, &rect);
|
||||
|
@ -346,20 +379,29 @@ HEADER_Refresh (HWND hwnd, HDC hdc)
|
|||
hOldFont = SelectObject (hdc, hFont);
|
||||
|
||||
/* draw Background */
|
||||
hbrBk = GetSysColorBrush(COLOR_3DFACE);
|
||||
FillRect(hdc, &rect, hbrBk);
|
||||
if (theme == NULL) {
|
||||
hbrBk = GetSysColorBrush(COLOR_3DFACE);
|
||||
FillRect(hdc, &rect, hbrBk);
|
||||
}
|
||||
|
||||
x = rect.left;
|
||||
for (i = 0; i < infoPtr->uNumItem; i++) {
|
||||
x = HEADER_DrawItem (hwnd, hdc, HEADER_OrderToIndex(hwnd,i), FALSE);
|
||||
x = HEADER_DrawItem (hwnd, hdc, HEADER_OrderToIndex(hwnd,i),
|
||||
infoPtr->iHotItem == i);
|
||||
}
|
||||
|
||||
if ((x <= rect.right) && (infoPtr->uNumItem > 0)) {
|
||||
rect.left = x;
|
||||
if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS)
|
||||
DrawEdge (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT);
|
||||
else
|
||||
DrawEdge (hdc, &rect, EDGE_ETCHED, BF_BOTTOM);
|
||||
if (theme != NULL) {
|
||||
DrawThemeBackground (theme, hdc, HP_HEADERITEM, HIS_NORMAL, &rect,
|
||||
NULL);
|
||||
}
|
||||
else {
|
||||
if (GetWindowLongW (hwnd, GWL_STYLE) & HDS_BUTTONS)
|
||||
DrawEdge (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT);
|
||||
else
|
||||
DrawEdge (hdc, &rect, EDGE_ETCHED, BF_BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
SelectObject (hdc, hOldFont);
|
||||
|
@ -1278,6 +1320,7 @@ HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
TEXTMETRICW tm;
|
||||
HFONT hOldFont;
|
||||
HDC hdc;
|
||||
BOOL themingActive = IsAppThemed() && IsThemeActive();
|
||||
|
||||
infoPtr = (HEADER_INFO *)Alloc (sizeof(HEADER_INFO));
|
||||
SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
|
||||
|
@ -1307,6 +1350,8 @@ HEADER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
SelectObject (hdc, hOldFont);
|
||||
ReleaseDC (0, hdc);
|
||||
|
||||
if (themingActive) OpenThemeData(hwnd, themeClass);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1317,6 +1362,7 @@ HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
HEADER_INFO *infoPtr = HEADER_GetInfoPtr (hwnd);
|
||||
HEADER_ITEM *lpItem;
|
||||
INT nItem;
|
||||
HTHEME theme;
|
||||
|
||||
if (infoPtr->items) {
|
||||
lpItem = infoPtr->items;
|
||||
|
@ -1332,6 +1378,9 @@ HEADER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
SetWindowLongPtrW (hwnd, 0, 0);
|
||||
Free (infoPtr);
|
||||
|
||||
theme = GetWindowTheme(hwnd);
|
||||
CloseThemeData(theme);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1692,6 +1741,16 @@ HEADER_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Update the theme handle after a theme change */
|
||||
static LRESULT HEADER_ThemeChanged(HWND hwnd)
|
||||
{
|
||||
HTHEME theme = GetWindowTheme(hwnd);
|
||||
CloseThemeData(theme);
|
||||
OpenThemeData(hwnd, themeClass);
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static LRESULT WINAPI
|
||||
HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
|
@ -1804,6 +1863,9 @@ HEADER_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_SIZE:
|
||||
return HEADER_Size (hwnd, wParam);
|
||||
|
||||
case WM_THEMECHANGED:
|
||||
return HEADER_ThemeChanged (hwnd);
|
||||
|
||||
case WM_PAINT:
|
||||
return HEADER_Paint (hwnd, wParam);
|
||||
|
||||
|
|
|
@ -2226,25 +2226,51 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
|
|||
HBITMAP hbmOldSrc;
|
||||
ICONINFO ii;
|
||||
BITMAP bmp;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%p %d %p)\n", himl, i, hIcon);
|
||||
|
||||
if (!is_valid(himl))
|
||||
return -1;
|
||||
if ((i >= himl->cMaxImage) || (i < -1))
|
||||
return -1;
|
||||
if (!is_valid(himl)) {
|
||||
ERR("invalid image list\n");
|
||||
return -1;
|
||||
}
|
||||
if ((i >= himl->cMaxImage) || (i < -1)) {
|
||||
ERR("invalid image index %d / %d\n", i, himl->cMaxImage);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hBestFitIcon = CopyImage(
|
||||
hIcon, IMAGE_ICON,
|
||||
himl->cx, himl->cy,
|
||||
LR_COPYFROMRESOURCE);
|
||||
/* the above will fail if the icon wasn't loaded from a resource, so try
|
||||
* again without LR_COPYFROMRESOURCE flag */
|
||||
if (!hBestFitIcon)
|
||||
hBestFitIcon = CopyImage(
|
||||
hIcon, IMAGE_ICON,
|
||||
himl->cx, himl->cy,
|
||||
0);
|
||||
if (!hBestFitIcon)
|
||||
return -1;
|
||||
|
||||
ret = GetIconInfo (hBestFitIcon, &ii);
|
||||
if (!ret) {
|
||||
DestroyIcon(hBestFitIcon);
|
||||
return -1;
|
||||
}
|
||||
|
||||
GetIconInfo (hBestFitIcon, &ii);
|
||||
if (ii.hbmMask == 0)
|
||||
ERR("no mask!\n");
|
||||
if (ii.hbmColor == 0)
|
||||
ERR("no color!\n");
|
||||
GetObjectA (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp);
|
||||
ret = GetObjectW (ii.hbmMask, sizeof(BITMAP), (LPVOID)&bmp);
|
||||
if (!ret) {
|
||||
ERR("couldn't get mask bitmap info\n");
|
||||
if (ii.hbmColor)
|
||||
DeleteObject (ii.hbmColor);
|
||||
if (ii.hbmMask)
|
||||
DeleteObject (ii.hbmMask);
|
||||
DestroyIcon(hBestFitIcon);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i == -1) {
|
||||
if (himl->cCurImage + 1 > himl->cMaxImage)
|
||||
|
@ -2276,8 +2302,7 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
|
|||
|
||||
SelectObject (hdcImage, hbmOldSrc);
|
||||
|
||||
if(hBestFitIcon)
|
||||
DestroyIcon(hBestFitIcon);
|
||||
DestroyIcon(hBestFitIcon);
|
||||
if (hdcImage)
|
||||
DeleteDC (hdcImage);
|
||||
if (ii.hbmColor)
|
||||
|
|
|
@ -185,6 +185,7 @@
|
|||
#include "winnls.h"
|
||||
#include "commctrl.h"
|
||||
#include "comctl32.h"
|
||||
#include "uxtheme.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
@ -396,6 +397,8 @@ typedef struct tagLISTVIEW_INFO
|
|||
TRACE("hwndSelf=%p, rcList=%s\n", iP->hwndSelf, debugrect(&iP->rcList)); \
|
||||
} while(0)
|
||||
|
||||
static const WCHAR themeClass[] = {'L','i','s','t','V','i','e','w',0};
|
||||
|
||||
/*
|
||||
* forward declarations
|
||||
*/
|
||||
|
@ -740,6 +743,12 @@ static inline LPCSTR debugscrollcode(int nScrollCode)
|
|||
|
||||
/******** Notification functions i************************************/
|
||||
|
||||
static LRESULT notify_forward_header(LISTVIEW_INFO *infoPtr, const NMHEADERW *lpnmh)
|
||||
{
|
||||
return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
|
||||
(WPARAM)lpnmh->hdr.idFrom, (LPARAM)lpnmh);
|
||||
}
|
||||
|
||||
static LRESULT notify_hdr(LISTVIEW_INFO *infoPtr, INT code, LPNMHDR pnmh)
|
||||
{
|
||||
LRESULT result;
|
||||
|
@ -1967,6 +1976,7 @@ static void LISTVIEW_GetItemMetrics(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVI
|
|||
if (lprcState) *lprcState = State;
|
||||
TRACE(" - state=%s\n", debugrect(&State));
|
||||
}
|
||||
else State.right = 0;
|
||||
|
||||
/************************************************************/
|
||||
/* compute ICON bounding box (ala LVM_GETITEMRECT) */
|
||||
|
@ -1989,7 +1999,7 @@ static void LISTVIEW_GetItemMetrics(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVI
|
|||
}
|
||||
else /* LVS_SMALLICON, LVS_LIST or LVS_REPORT */
|
||||
{
|
||||
Icon.left = State.right;
|
||||
Icon.left = State.right;
|
||||
Icon.top = Box.top;
|
||||
Icon.right = Icon.left;
|
||||
if (infoPtr->himlSmall &&
|
||||
|
@ -2001,6 +2011,7 @@ static void LISTVIEW_GetItemMetrics(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVI
|
|||
if(lprcIcon) *lprcIcon = Icon;
|
||||
TRACE(" - icon=%s\n", debugrect(&Icon));
|
||||
}
|
||||
else Icon.right = 0;
|
||||
|
||||
/************************************************************/
|
||||
/* compute LABEL bounding box (ala LVM_GETITEMRECT) */
|
||||
|
@ -4812,6 +4823,7 @@ static INT LISTVIEW_FindItemW(LISTVIEW_INFO *infoPtr, INT nStart,
|
|||
}
|
||||
bNearest = TRUE;
|
||||
}
|
||||
else Destination.x = Destination.y = 0;
|
||||
|
||||
/* if LVFI_PARAM is specified, all other flags are ignored */
|
||||
if (lpFindInfo->flags & LVFI_PARAM)
|
||||
|
@ -7444,6 +7456,25 @@ static BOOL LISTVIEW_SortItems(LISTVIEW_INFO *infoPtr, PFNLVCOMPARE pfnCompare,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***
|
||||
* DESCRIPTION:
|
||||
* Update theme handle after a theme change.
|
||||
*
|
||||
* PARAMETER(S):
|
||||
* [I] infoPtr : valid pointer to the listview structure
|
||||
*
|
||||
* RETURN:
|
||||
* SUCCESS : 0
|
||||
* FAILURE : something else
|
||||
*/
|
||||
static LRESULT LISTVIEW_ThemeChanged(LISTVIEW_INFO *infoPtr)
|
||||
{
|
||||
HTHEME theme = GetWindowTheme(infoPtr->hwndSelf);
|
||||
CloseThemeData(theme);
|
||||
OpenThemeData(infoPtr->hwndSelf, themeClass);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
* DESCRIPTION:
|
||||
* Updates an items or rearranges the listview control.
|
||||
|
@ -7489,6 +7520,7 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
|
|||
LISTVIEW_INFO *infoPtr;
|
||||
UINT uView = lpcs->style & LVS_TYPEMASK;
|
||||
LOGFONTW logFont;
|
||||
BOOL themingActive = IsAppThemed() && IsThemeActive();
|
||||
|
||||
TRACE("(lpcs=%p)\n", lpcs);
|
||||
|
||||
|
@ -7571,6 +7603,8 @@ static LRESULT LISTVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
|
|||
}
|
||||
}
|
||||
|
||||
if (themingActive) OpenThemeData(hwnd, themeClass);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
@ -7584,6 +7618,24 @@ fail:
|
|||
return -1;
|
||||
}
|
||||
|
||||
/***
|
||||
* DESCRIPTION:
|
||||
* Destroys the listview control.
|
||||
*
|
||||
* PARAMETER(S):
|
||||
* [I] infoPtr : valid pointer to the listview structure
|
||||
*
|
||||
* RETURN:
|
||||
* Success: 0
|
||||
* Failure: -1
|
||||
*/
|
||||
static LRESULT LISTVIEW_Destroy(LISTVIEW_INFO *infoPtr)
|
||||
{
|
||||
HTHEME theme = GetWindowTheme(infoPtr->hwndSelf);
|
||||
CloseThemeData(theme);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
* DESCRIPTION:
|
||||
* Enables the listview control.
|
||||
|
@ -8274,10 +8326,15 @@ static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADE
|
|||
|
||||
switch (lpnmh->hdr.code)
|
||||
{
|
||||
case HDN_TRACKW:
|
||||
case HDN_TRACKA:
|
||||
case HDN_ITEMCHANGINGW:
|
||||
case HDN_ITEMCHANGINGA:
|
||||
return notify_forward_header(infoPtr, lpnmh);
|
||||
case HDN_ITEMCHANGEDW:
|
||||
case HDN_ITEMCHANGEDA:
|
||||
notify_forward_header(infoPtr, lpnmh);
|
||||
/* Fall through */
|
||||
case HDN_TRACKW:
|
||||
case HDN_TRACKA:
|
||||
{
|
||||
COLUMN_INFO *lpColumnInfo;
|
||||
INT dx, cxy;
|
||||
|
@ -8347,6 +8404,53 @@ static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADE
|
|||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
* DESCRIPTION:
|
||||
* Paint non-client area of control.
|
||||
*
|
||||
* PARAMETER(S):
|
||||
* [I] infoPtr : valid pointer to the listview structureof the sender
|
||||
* [I] region : update region
|
||||
*
|
||||
* RETURN:
|
||||
* TRUE - frame was painted
|
||||
* FALSE - call default window proc
|
||||
*/
|
||||
static BOOL LISTVIEW_NCPaint(LISTVIEW_INFO *infoPtr, HRGN region)
|
||||
{
|
||||
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
|
||||
BOOL themingActive = IsAppThemed() && IsThemeActive();
|
||||
BOOL doTheming = themingActive && (theme != NULL);
|
||||
HDC dc;
|
||||
RECT r;
|
||||
HRGN cliprgn;
|
||||
int cxEdge = GetSystemMetrics (SM_CXEDGE),
|
||||
cyEdge = GetSystemMetrics (SM_CYEDGE);
|
||||
|
||||
if (!doTheming) return FALSE;
|
||||
|
||||
GetWindowRect(infoPtr->hwndSelf, &r);
|
||||
|
||||
cliprgn = CreateRectRgn (r.left + cxEdge, r.top + cyEdge,
|
||||
r.right - cxEdge, r.bottom - cyEdge);
|
||||
if (region != (HRGN)1)
|
||||
CombineRgn (cliprgn, cliprgn, region, RGN_AND);
|
||||
OffsetRect(&r, -r.left, -r.top);
|
||||
|
||||
dc = GetDCEx(infoPtr->hwndSelf, region, DCX_WINDOW|DCX_INTERSECTRGN);
|
||||
OffsetRect(&r, -r.left, -r.top);
|
||||
|
||||
if (IsThemeBackgroundPartiallyTransparent (theme, 0, 0))
|
||||
DrawThemeParentBackground(infoPtr->hwndSelf, dc, &r);
|
||||
DrawThemeBackground (theme, dc, 0, 0, &r, 0);
|
||||
ReleaseDC(infoPtr->hwndSelf, dc);
|
||||
|
||||
/* Call default proc to get the scrollbars etc. painted */
|
||||
DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)cliprgn, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***
|
||||
* DESCRIPTION:
|
||||
* Determines the type of structure to use.
|
||||
|
@ -9244,6 +9348,9 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_CREATE:
|
||||
return LISTVIEW_Create(hwnd, (LPCREATESTRUCTW)lParam);
|
||||
|
||||
case WM_DESTROY:
|
||||
return LISTVIEW_Destroy(infoPtr);
|
||||
|
||||
case WM_ENABLE:
|
||||
return LISTVIEW_Enable(infoPtr, (BOOL)wParam);
|
||||
|
||||
|
@ -9283,6 +9390,11 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_NCDESTROY:
|
||||
return LISTVIEW_NCDestroy(infoPtr);
|
||||
|
||||
case WM_NCPAINT:
|
||||
if (LISTVIEW_NCPaint(infoPtr, (HRGN)wParam))
|
||||
return 0;
|
||||
goto fwd_msg;
|
||||
|
||||
case WM_NOTIFY:
|
||||
if (lParam && ((LPNMHDR)lParam)->hwndFrom == infoPtr->hwndHeader)
|
||||
return LISTVIEW_HeaderNotification(infoPtr, (LPNMHEADERW)lParam);
|
||||
|
@ -9331,6 +9443,8 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
return 0;
|
||||
|
||||
/* case WM_TIMER: */
|
||||
case WM_THEMECHANGED:
|
||||
return LISTVIEW_ThemeChanged(infoPtr);
|
||||
|
||||
case WM_VSCROLL:
|
||||
return LISTVIEW_VScroll(infoPtr, (INT)LOWORD(wParam), 0, (HWND)lParam);
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
* - Enforcing of minimal wizard size
|
||||
* - Messages:
|
||||
* o PSM_GETRESULT
|
||||
* o PSM_IDTOINDEX
|
||||
* o PSM_INSERTPAGE
|
||||
* o PSM_RECALCPAGESIZES
|
||||
* o PSM_SETHEADERSUBTITLE
|
||||
|
@ -45,7 +44,6 @@
|
|||
* o PSN_QUERYINITIALFOCUS
|
||||
* o PSN_TRANSLATEACCELERATOR
|
||||
* - Styles:
|
||||
* o PSH_WIZARDHASFINISH
|
||||
* o PSH_RTLREADING
|
||||
* o PSH_STRETCHWATERMARK
|
||||
* o PSH_USEPAGELANG
|
||||
|
@ -68,6 +66,7 @@
|
|||
#include "commctrl.h"
|
||||
#include "prsht.h"
|
||||
#include "comctl32.h"
|
||||
#include "uxtheme.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
@ -121,6 +120,7 @@ typedef struct tagPropSheetInfo
|
|||
BOOL isModeless;
|
||||
BOOL hasHelp;
|
||||
BOOL hasApply;
|
||||
BOOL hasFinish;
|
||||
BOOL useCallback;
|
||||
BOOL restartWindows;
|
||||
BOOL rebootSystem;
|
||||
|
@ -233,13 +233,11 @@ static VOID PROPSHEET_UnImplementedFlags(DWORD dwFlags)
|
|||
|
||||
/*
|
||||
* unhandled header flags:
|
||||
* PSH_WIZARDHASFINISH 0x00000010
|
||||
* PSH_RTLREADING 0x00000800
|
||||
* PSH_STRETCHWATERMARK 0x00040000
|
||||
* PSH_USEPAGELANG 0x00200000
|
||||
*/
|
||||
|
||||
add_flag(PSH_WIZARDHASFINISH);
|
||||
add_flag(PSH_RTLREADING);
|
||||
add_flag(PSH_STRETCHWATERMARK);
|
||||
add_flag(PSH_USEPAGELANG);
|
||||
|
@ -341,6 +339,7 @@ static BOOL PROPSHEET_CollectSheetInfoA(LPCPROPSHEETHEADERA lppsh,
|
|||
|
||||
psInfo->hasHelp = dwFlags & PSH_HASHELP;
|
||||
psInfo->hasApply = !(dwFlags & PSH_NOAPPLYNOW);
|
||||
psInfo->hasFinish = dwFlags & PSH_WIZARDHASFINISH;
|
||||
psInfo->useCallback = (dwFlags & PSH_USECALLBACK )&& (lppsh->pfnCallback);
|
||||
psInfo->isModeless = dwFlags & PSH_MODELESS;
|
||||
|
||||
|
@ -396,6 +395,7 @@ static BOOL PROPSHEET_CollectSheetInfoW(LPCPROPSHEETHEADERW lppsh,
|
|||
|
||||
psInfo->hasHelp = dwFlags & PSH_HASHELP;
|
||||
psInfo->hasApply = !(dwFlags & PSH_NOAPPLYNOW);
|
||||
psInfo->hasFinish = dwFlags & PSH_WIZARDHASFINISH;
|
||||
psInfo->useCallback = (dwFlags & PSH_USECALLBACK) && (lppsh->pfnCallback);
|
||||
psInfo->isModeless = dwFlags & PSH_MODELESS;
|
||||
|
||||
|
@ -1004,6 +1004,8 @@ static BOOL PROPSHEET_AdjustButtonsWizard(HWND hwndParent,
|
|||
|
||||
if (psInfo->hasHelp)
|
||||
num_buttons++;
|
||||
if (psInfo->hasFinish)
|
||||
num_buttons++;
|
||||
|
||||
/*
|
||||
* Obtain the size of the buttons.
|
||||
|
@ -1024,40 +1026,47 @@ static BOOL PROPSHEET_AdjustButtonsWizard(HWND hwndParent,
|
|||
* All buttons will be at this y coordinate.
|
||||
*/
|
||||
y = rcSheet.bottom - (padding.y + buttonHeight);
|
||||
|
||||
/*
|
||||
* Position the Next and the Finish buttons.
|
||||
*/
|
||||
hwndButton = GetDlgItem(hwndParent, IDC_NEXT_BUTTON);
|
||||
|
||||
x = rcSheet.right - ((padding.x + buttonWidth) * (num_buttons - 1));
|
||||
|
||||
SetWindowPos(hwndButton, 0, x, y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
hwndButton = GetDlgItem(hwndParent, IDC_FINISH_BUTTON);
|
||||
|
||||
SetWindowPos(hwndButton, 0, x, y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
ShowWindow(hwndButton, SW_HIDE);
|
||||
|
||||
|
||||
/*
|
||||
* Position the Back button.
|
||||
*/
|
||||
hwndButton = GetDlgItem(hwndParent, IDC_BACK_BUTTON);
|
||||
|
||||
x -= buttonWidth;
|
||||
x = rcSheet.right - ((padding.x + buttonWidth) * (num_buttons - 1)) - buttonWidth;
|
||||
|
||||
SetWindowPos(hwndButton, 0, x, y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
/*
|
||||
* Position the Next button.
|
||||
*/
|
||||
hwndButton = GetDlgItem(hwndParent, IDC_NEXT_BUTTON);
|
||||
|
||||
x += buttonWidth;
|
||||
|
||||
SetWindowPos(hwndButton, 0, x, y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
/*
|
||||
* Position the Finish button.
|
||||
*/
|
||||
hwndButton = GetDlgItem(hwndParent, IDC_FINISH_BUTTON);
|
||||
|
||||
if (psInfo->hasFinish)
|
||||
x += padding.x + buttonWidth;
|
||||
|
||||
SetWindowPos(hwndButton, 0, x, y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
if (!psInfo->hasFinish)
|
||||
ShowWindow(hwndButton, SW_HIDE);
|
||||
|
||||
/*
|
||||
* Position the Cancel button.
|
||||
*/
|
||||
hwndButton = GetDlgItem(hwndParent, IDCANCEL);
|
||||
|
||||
x = rcSheet.right - ((padding.x + buttonWidth) * (num_buttons - 2));
|
||||
x += padding.x + buttonWidth;
|
||||
|
||||
SetWindowPos(hwndButton, 0, x, y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
@ -1069,7 +1078,7 @@ static BOOL PROPSHEET_AdjustButtonsWizard(HWND hwndParent,
|
|||
|
||||
if (psInfo->hasHelp)
|
||||
{
|
||||
x = rcSheet.right - (padding.x + buttonWidth);
|
||||
x += padding.x + buttonWidth;
|
||||
|
||||
SetWindowPos(hwndButton, 0, x, y, 0, 0,
|
||||
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
@ -1533,6 +1542,8 @@ static BOOL PROPSHEET_CreatePage(HWND hwndParent,
|
|||
SetWindowSubclass(hwndPage, PROPSHEET_WizardSubclassProc, 1,
|
||||
(DWORD_PTR)ppshpage);
|
||||
}
|
||||
if (!(psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD))
|
||||
EnableThemeDialogTexture (hwndPage, ETDT_ENABLETAB);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1623,9 +1634,6 @@ static BOOL PROPSHEET_ShowPage(HWND hwndDlg, int index, PropSheetInfo * psInfo)
|
|||
ShowWindow(hwndLineHeader, SW_SHOW);
|
||||
}
|
||||
|
||||
InvalidateRgn(hwndDlg, NULL, TRUE);
|
||||
UpdateWindow(hwndDlg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2196,6 +2204,7 @@ static void PROPSHEET_SetTitleW(HWND hwndDlg, DWORD dwStyle, LPCWSTR lpszText)
|
|||
*/
|
||||
static void PROPSHEET_SetFinishTextA(HWND hwndDlg, LPCSTR lpszText)
|
||||
{
|
||||
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwndDlg, PropSheetInfoStr);
|
||||
HWND hwndButton = GetDlgItem(hwndDlg, IDC_FINISH_BUTTON);
|
||||
|
||||
TRACE("'%s'\n", lpszText);
|
||||
|
@ -2211,9 +2220,12 @@ static void PROPSHEET_SetFinishTextA(HWND hwndDlg, LPCSTR lpszText)
|
|||
hwndButton = GetDlgItem(hwndDlg, IDC_BACK_BUTTON);
|
||||
ShowWindow(hwndButton, SW_HIDE);
|
||||
|
||||
/* Hide Next button */
|
||||
hwndButton = GetDlgItem(hwndDlg, IDC_NEXT_BUTTON);
|
||||
ShowWindow(hwndButton, SW_HIDE);
|
||||
if (!psInfo->hasFinish)
|
||||
{
|
||||
/* Hide Next button */
|
||||
hwndButton = GetDlgItem(hwndDlg, IDC_NEXT_BUTTON);
|
||||
ShowWindow(hwndButton, SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -2221,6 +2233,7 @@ static void PROPSHEET_SetFinishTextA(HWND hwndDlg, LPCSTR lpszText)
|
|||
*/
|
||||
static void PROPSHEET_SetFinishTextW(HWND hwndDlg, LPCWSTR lpszText)
|
||||
{
|
||||
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwndDlg, PropSheetInfoStr);
|
||||
HWND hwndButton = GetDlgItem(hwndDlg, IDC_FINISH_BUTTON);
|
||||
|
||||
TRACE("'%s'\n", debugstr_w(lpszText));
|
||||
|
@ -2236,9 +2249,12 @@ static void PROPSHEET_SetFinishTextW(HWND hwndDlg, LPCWSTR lpszText)
|
|||
hwndButton = GetDlgItem(hwndDlg, IDC_BACK_BUTTON);
|
||||
ShowWindow(hwndButton, SW_HIDE);
|
||||
|
||||
/* Hide Next button */
|
||||
hwndButton = GetDlgItem(hwndDlg, IDC_NEXT_BUTTON);
|
||||
ShowWindow(hwndButton, SW_HIDE);
|
||||
if (!psInfo->hasFinish)
|
||||
{
|
||||
/* Hide Next button */
|
||||
hwndButton = GetDlgItem(hwndDlg, IDC_NEXT_BUTTON);
|
||||
ShowWindow(hwndButton, SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -2439,6 +2455,8 @@ static BOOL PROPSHEET_RemovePage(HWND hwndDlg,
|
|||
*/
|
||||
static void PROPSHEET_SetWizButtons(HWND hwndDlg, DWORD dwFlags)
|
||||
{
|
||||
PropSheetInfo* psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
|
||||
PropSheetInfoStr);
|
||||
HWND hwndBack = GetDlgItem(hwndDlg, IDC_BACK_BUTTON);
|
||||
HWND hwndNext = GetDlgItem(hwndDlg, IDC_NEXT_BUTTON);
|
||||
HWND hwndFinish = GetDlgItem(hwndDlg, IDC_FINISH_BUTTON);
|
||||
|
@ -2454,8 +2472,11 @@ static void PROPSHEET_SetWizButtons(HWND hwndDlg, DWORD dwFlags)
|
|||
|
||||
if (dwFlags & PSWIZB_NEXT)
|
||||
{
|
||||
/* Hide the Finish button */
|
||||
ShowWindow(hwndFinish, SW_HIDE);
|
||||
if (!psInfo->hasFinish)
|
||||
{
|
||||
/* Hide the Finish button */
|
||||
ShowWindow(hwndFinish, SW_HIDE);
|
||||
}
|
||||
|
||||
/* Show and enable the Next button */
|
||||
ShowWindow(hwndNext, SW_SHOW);
|
||||
|
@ -2465,20 +2486,27 @@ static void PROPSHEET_SetWizButtons(HWND hwndDlg, DWORD dwFlags)
|
|||
SendMessageW(hwndDlg, DM_SETDEFID, IDC_NEXT_BUTTON, 0);
|
||||
}
|
||||
|
||||
if ((dwFlags & PSWIZB_FINISH) || (dwFlags & PSWIZB_DISABLEDFINISH))
|
||||
if (!psInfo->hasFinish)
|
||||
{
|
||||
/* Hide the Next button */
|
||||
ShowWindow(hwndNext, SW_HIDE);
|
||||
if ((dwFlags & PSWIZB_FINISH) || (dwFlags & PSWIZB_DISABLEDFINISH))
|
||||
{
|
||||
/* Hide the Next button */
|
||||
ShowWindow(hwndNext, SW_HIDE);
|
||||
|
||||
/* Show the Finish button */
|
||||
ShowWindow(hwndFinish, SW_SHOW);
|
||||
|
||||
/* Show the Finish button */
|
||||
ShowWindow(hwndFinish, SW_SHOW);
|
||||
if (!(dwFlags & PSWIZB_DISABLEDFINISH))
|
||||
{
|
||||
EnableWindow(hwndFinish, TRUE);
|
||||
|
||||
if (dwFlags & PSWIZB_FINISH)
|
||||
EnableWindow(hwndFinish, TRUE);
|
||||
|
||||
/* Set the Finish button as the default pushbutton */
|
||||
SendMessageW(hwndDlg, DM_SETDEFID, IDC_FINISH_BUTTON, 0);
|
||||
/* Set the Finish button as the default pushbutton */
|
||||
SendMessageW(hwndDlg, DM_SETDEFID, IDC_FINISH_BUTTON, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(dwFlags & PSWIZB_DISABLEDFINISH))
|
||||
EnableWindow(hwndFinish, TRUE);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -2596,7 +2624,17 @@ static LRESULT PROPSHEET_IndexToPage(HWND hwndDlg, int iPageIndex)
|
|||
*/
|
||||
static LRESULT PROPSHEET_IdToIndex(HWND hwndDlg, int iPageId)
|
||||
{
|
||||
FIXME("(%p, %d): stub\n", hwndDlg, iPageId);
|
||||
int index;
|
||||
LPCPROPSHEETPAGEW psp;
|
||||
PropSheetInfo * psInfo = (PropSheetInfo*) GetPropW(hwndDlg,
|
||||
PropSheetInfoStr);
|
||||
TRACE("(%p, %d)\n", hwndDlg, iPageId);
|
||||
for (index = 0; index < psInfo->nPages; index++) {
|
||||
psp = (LPCPROPSHEETPAGEW)psInfo->proppage[index].hpage;
|
||||
if (psp->u.pszTemplate == (LPCWSTR)iPageId)
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3473,6 +3511,10 @@ PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case WM_SYSCOLORCHANGE:
|
||||
COMCTL32_RefreshSysColors();
|
||||
return FALSE;
|
||||
|
||||
case PSM_GETCURRENTPAGEHWND:
|
||||
{
|
||||
|
|
|
@ -118,7 +118,6 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
DWORD dwStructSize; /* size of TBBUTTON struct */
|
||||
INT nHeight; /* height of the toolbar */
|
||||
INT nWidth; /* width of the toolbar */
|
||||
RECT client_rect;
|
||||
RECT rcBound; /* bounding rectangle */
|
||||
|
@ -156,8 +155,6 @@ typedef struct
|
|||
HWND hwndToolTip; /* handle to tool tip control */
|
||||
HWND hwndNotify; /* handle to the window that gets notifications */
|
||||
HWND hwndSelf; /* my own handle */
|
||||
BOOL bBtnTranspnt; /* button transparency flag */
|
||||
BOOL bAutoSize; /* auto size deadlock indicator */
|
||||
BOOL bAnchor; /* anchor highlight enabled */
|
||||
BOOL bDoRedraw; /* Redraw status */
|
||||
BOOL bDragOutSent; /* has TBN_DRAGOUT notification been sent for this drag? */
|
||||
|
@ -249,6 +246,7 @@ static VOID TOOLBAR_DeleteImageList(PIMLENTRY **pies, INT *cies);
|
|||
static HIMAGELIST TOOLBAR_InsertImageList(PIMLENTRY **pies, INT *cies, HIMAGELIST himl, INT id);
|
||||
static LRESULT TOOLBAR_LButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam);
|
||||
static void TOOLBAR_SetHotItemEx (TOOLBAR_INFO *infoPtr, INT nHit, DWORD dwReason);
|
||||
static LRESULT TOOLBAR_AutoSize(HWND hwnd);
|
||||
|
||||
static LRESULT
|
||||
TOOLBAR_NotifyFormat(TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam);
|
||||
|
@ -580,7 +578,7 @@ TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, RECT *rcText, LPWSTR lpText,
|
|||
else if ((state & CDIS_MARKED) && !(infoPtr->dwItemCDFlag & TBCDRF_NOMARK)) {
|
||||
clrOld = SetTextColor (hdc, tbcd->clrTextHighlight);
|
||||
clrOldBk = SetBkColor (hdc, tbcd->clrMark);
|
||||
oldBkMode = SetBkMode (hdc, OPAQUE); /* FIXME: should this be in the NMTBCUSTOMDRAW structure? */
|
||||
oldBkMode = SetBkMode (hdc, tbcd->nHLStringBkMode);
|
||||
}
|
||||
else {
|
||||
clrOld = SetTextColor (hdc, tbcd->clrText);
|
||||
|
@ -671,7 +669,7 @@ TOOLBAR_TranslateState(TBUTTON_INFO *btnPtr)
|
|||
retstate |= (btnPtr->fsState & TBSTATE_ENABLED) ? 0 : CDIS_DISABLED;
|
||||
retstate |= (btnPtr->fsState & TBSTATE_MARKED ) ? CDIS_MARKED : 0;
|
||||
retstate |= (btnPtr->bHot ) ? CDIS_HOT : 0;
|
||||
retstate |= (btnPtr->fsState & TBSTATE_INDETERMINATE) ? CDIS_INDETERMINATE : 0;
|
||||
retstate |= ((btnPtr->fsState & (TBSTATE_ENABLED|TBSTATE_INDETERMINATE)) == (TBSTATE_ENABLED|TBSTATE_INDETERMINATE)) ? CDIS_INDETERMINATE : 0;
|
||||
/* NOTE: we don't set CDIS_GRAYED, CDIS_FOCUS, CDIS_DEFAULT */
|
||||
return retstate;
|
||||
}
|
||||
|
@ -815,6 +813,7 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
|
|||
NMTBCUSTOMDRAW tbcd;
|
||||
DWORD ntfret;
|
||||
INT offset;
|
||||
INT oldBkMode;
|
||||
|
||||
rc = btnPtr->rect;
|
||||
CopyRect (&rcArrow, &rc);
|
||||
|
@ -894,8 +893,8 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
|
|||
tbcd.clrBtnHighlight = comctl32_color.clrBtnHighlight;
|
||||
tbcd.clrMark = comctl32_color.clrHighlight;
|
||||
tbcd.clrHighlightHotTrack = 0;
|
||||
tbcd.nStringBkMode = (infoPtr->bBtnTranspnt) ? TRANSPARENT : OPAQUE;
|
||||
tbcd.nHLStringBkMode = (infoPtr->bBtnTranspnt) ? TRANSPARENT : OPAQUE;
|
||||
tbcd.nStringBkMode = TRANSPARENT;
|
||||
tbcd.nHLStringBkMode = OPAQUE;
|
||||
/* MSDN says that this is the text rectangle.
|
||||
* But (why always a but) tracing of v5.7 of native shows
|
||||
* that this is really a *relative* rectangle based on the
|
||||
|
@ -983,8 +982,10 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
|
|||
if (drawSepDropDownArrow)
|
||||
TOOLBAR_DrawSepDDArrow(infoPtr, &tbcd, &rcArrow, btnPtr->bDropDownPressed);
|
||||
|
||||
oldBkMode = SetBkMode (hdc, tbcd.nStringBkMode);
|
||||
if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
|
||||
TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd);
|
||||
SetBkMode (hdc, oldBkMode);
|
||||
|
||||
TOOLBAR_DrawImage(infoPtr, btnPtr, rcBitmap.left, rcBitmap.top, &tbcd);
|
||||
|
||||
|
@ -1007,16 +1008,8 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc)
|
|||
FINALNOTIFY:
|
||||
if (infoPtr->dwItemCustDraw & CDRF_NOTIFYPOSTPAINT)
|
||||
{
|
||||
tbcd.nmcd.dwDrawStage = CDDS_ITEMPOSTPAINT;
|
||||
tbcd.nmcd.hdc = hdc;
|
||||
tbcd.nmcd.rc = rc;
|
||||
tbcd.nmcd.dwItemSpec = btnPtr->idCommand;
|
||||
tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr);
|
||||
tbcd.nmcd.lItemlParam = btnPtr->dwData;
|
||||
tbcd.rcText = rcText;
|
||||
tbcd.nStringBkMode = (infoPtr->bBtnTranspnt) ? TRANSPARENT : OPAQUE;
|
||||
tbcd.nHLStringBkMode = (infoPtr->bBtnTranspnt) ? TRANSPARENT : OPAQUE;
|
||||
ntfret = TOOLBAR_SendNotify(&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
|
||||
tbcd.nmcd.dwDrawStage = CDDS_ITEMPOSTPAINT;
|
||||
TOOLBAR_SendNotify(&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1027,7 +1020,7 @@ TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
|
|||
{
|
||||
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
|
||||
TBUTTON_INFO *btnPtr;
|
||||
INT i, oldBKmode = 0;
|
||||
INT i;
|
||||
RECT rcTemp, rcClient;
|
||||
NMTBCUSTOMDRAW tbcd;
|
||||
DWORD ntfret;
|
||||
|
@ -1055,9 +1048,6 @@ TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
|
|||
ntfret = TOOLBAR_SendNotify(&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
|
||||
infoPtr->dwBaseCustDraw = ntfret & 0xffff;
|
||||
|
||||
if (infoPtr->bBtnTranspnt)
|
||||
oldBKmode = SetBkMode (hdc, TRANSPARENT);
|
||||
|
||||
GetClientRect(hwnd, &rcClient);
|
||||
|
||||
/* redraw necessary buttons */
|
||||
|
@ -1092,9 +1082,6 @@ TOOLBAR_Refresh (HWND hwnd, HDC hdc, PAINTSTRUCT* ps)
|
|||
COMCTL32_DrawInsertMark(hdc, &rcInsertMark, infoPtr->clrInsertMark, FALSE);
|
||||
}
|
||||
|
||||
if (infoPtr->bBtnTranspnt && (oldBKmode != TRANSPARENT))
|
||||
SetBkMode (hdc, oldBKmode);
|
||||
|
||||
if (infoPtr->dwBaseCustDraw & CDRF_NOTIFYPOSTPAINT)
|
||||
{
|
||||
ZeroMemory (&tbcd, sizeof(NMTBCUSTOMDRAW));
|
||||
|
@ -1175,12 +1162,20 @@ TOOLBAR_CalcStrings (HWND hwnd, LPSIZE lpSize)
|
|||
lpSize->cx = 0;
|
||||
lpSize->cy = 0;
|
||||
|
||||
if(infoPtr->nMaxTextRows == 0)
|
||||
if (infoPtr->nMaxTextRows == 0)
|
||||
return;
|
||||
|
||||
hdc = GetDC (hwnd);
|
||||
hOldFont = SelectObject (hdc, infoPtr->hFont);
|
||||
|
||||
if (infoPtr->nNumButtons == 0)
|
||||
{
|
||||
TEXTMETRICW tm;
|
||||
|
||||
GetTextMetricsW(hdc, &tm);
|
||||
lpSize->cy = tm.tmHeight;
|
||||
}
|
||||
|
||||
btnPtr = infoPtr->buttons;
|
||||
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) {
|
||||
if(TOOLBAR_HasText(infoPtr, btnPtr))
|
||||
|
@ -1557,7 +1552,6 @@ TOOLBAR_CalcToolbar (HWND hwnd)
|
|||
INT x, y, cx, cy;
|
||||
SIZE sizeString, sizeButton;
|
||||
BOOL bWrap;
|
||||
BOOL usesBitmaps = FALSE;
|
||||
BOOL validImageList = FALSE;
|
||||
BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle);
|
||||
|
||||
|
@ -1565,14 +1559,9 @@ TOOLBAR_CalcToolbar (HWND hwnd)
|
|||
|
||||
TOOLBAR_DumpToolbar (infoPtr, __LINE__);
|
||||
|
||||
for (i = 0; i < infoPtr->nNumButtons && !usesBitmaps; i++)
|
||||
{
|
||||
if (TOOLBAR_IsValidBitmapIndex(infoPtr,infoPtr->buttons[i].iBitmap))
|
||||
usesBitmaps = TRUE;
|
||||
}
|
||||
if (TOOLBAR_IsValidImageList(infoPtr, 0))
|
||||
validImageList = TRUE;
|
||||
sizeButton = TOOLBAR_MeasureButton(infoPtr, sizeString, usesBitmaps, validImageList);
|
||||
sizeButton = TOOLBAR_MeasureButton(infoPtr, sizeString, TRUE, validImageList);
|
||||
infoPtr->nButtonWidth = sizeButton.cx;
|
||||
infoPtr->nButtonHeight = sizeButton.cy;
|
||||
|
||||
|
@ -1584,14 +1573,14 @@ TOOLBAR_CalcToolbar (HWND hwnd)
|
|||
TOOLBAR_WrapToolbar( hwnd, dwStyle );
|
||||
|
||||
x = infoPtr->nIndent;
|
||||
y = 0;
|
||||
if (infoPtr->dwStyle & TBSTYLE_FLAT)
|
||||
y = 0;
|
||||
else
|
||||
y = TOP_BORDER;
|
||||
|
||||
/* from above, minimum is a button, and possible text */
|
||||
cx = infoPtr->nButtonWidth;
|
||||
|
||||
infoPtr->nHeight = infoPtr->nButtonHeight;
|
||||
|
||||
cy = infoPtr->nHeight;
|
||||
cy = infoPtr->nButtonHeight;
|
||||
|
||||
nRows = nSepRows = 0;
|
||||
|
||||
|
@ -1613,7 +1602,7 @@ TOOLBAR_CalcToolbar (HWND hwnd)
|
|||
continue;
|
||||
}
|
||||
|
||||
cy = infoPtr->nHeight;
|
||||
cy = infoPtr->nButtonHeight;
|
||||
|
||||
/* UNDOCUMENTED: If a separator has a non zero bitmap index, */
|
||||
/* it is the actual width of the separator. This is used for */
|
||||
|
@ -1728,27 +1717,7 @@ TOOLBAR_CalcToolbar (HWND hwnd)
|
|||
/* infoPtr->nRows is the number of rows on the toolbar */
|
||||
infoPtr->nRows = nRows + nSepRows + 1;
|
||||
|
||||
#if 0
|
||||
/********************************************************************
|
||||
* The following while interesting, does not match the values *
|
||||
* created above for the button rectangles, nor the rcBound rect. *
|
||||
* We will comment it out and remove it later. *
|
||||
* *
|
||||
* The problem showed up as heights in the pager control that was *
|
||||
* wrong. *
|
||||
********************************************************************/
|
||||
|
||||
/* nSepRows * (infoPtr->nBitmapHeight + 1) is the space following */
|
||||
/* the last row. */
|
||||
infoPtr->nHeight = TOP_BORDER + (nRows + 1) * infoPtr->nButtonHeight +
|
||||
nSepRows * (SEPARATOR_WIDTH * 2 / 3) +
|
||||
nSepRows * (infoPtr->nBitmapHeight + 1) +
|
||||
BOTTOM_BORDER;
|
||||
#endif
|
||||
|
||||
infoPtr->nHeight = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
|
||||
|
||||
TRACE("toolbar height %d, button width %d\n", infoPtr->nHeight, infoPtr->nButtonWidth);
|
||||
TRACE("toolbar button width %d\n", infoPtr->nButtonWidth);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2731,7 +2700,7 @@ TOOLBAR_AddBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
TBITMAP_INFO *oldBitmaps = infoPtr->bitmaps;
|
||||
infoPtr->bitmaps = Alloc((infoPtr->nNumBitmapInfos + 1) * sizeof(TBITMAP_INFO));
|
||||
memcpy(&infoPtr->bitmaps[0], &oldBitmaps[0], infoPtr->nNumBitmapInfos);
|
||||
memcpy(&infoPtr->bitmaps[0], &oldBitmaps[0], infoPtr->nNumBitmapInfos * sizeof(TBITMAP_INFO));
|
||||
}
|
||||
|
||||
infoPtr->bitmaps[infoPtr->nNumBitmapInfos].nButtons = nButtons;
|
||||
|
@ -2821,6 +2790,7 @@ TOOLBAR_AddButtonsA (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
|
||||
TOOLBAR_CalcToolbar (hwnd);
|
||||
TOOLBAR_AutoSize (hwnd);
|
||||
|
||||
TOOLBAR_DumpToolbar (infoPtr, __LINE__);
|
||||
|
||||
|
@ -2889,6 +2859,7 @@ TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
|
||||
TOOLBAR_CalcToolbar (hwnd);
|
||||
TOOLBAR_AutoSize (hwnd);
|
||||
|
||||
TOOLBAR_DumpToolbar (infoPtr, __LINE__);
|
||||
|
||||
|
@ -3082,66 +3053,66 @@ TOOLBAR_AutoSize (HWND hwnd)
|
|||
{
|
||||
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
|
||||
RECT parent_rect;
|
||||
RECT window_rect;
|
||||
HWND parent;
|
||||
INT x, y;
|
||||
INT cx, cy;
|
||||
UINT uPosFlags = SWP_NOZORDER;
|
||||
|
||||
TRACE("resize forced, style=%lx!\n", infoPtr->dwStyle);
|
||||
TRACE("auto sizing, style=%lx!\n", infoPtr->dwStyle);
|
||||
|
||||
parent = GetParent (hwnd);
|
||||
|
||||
if (!parent || !infoPtr->bDoRedraw)
|
||||
return 0;
|
||||
|
||||
GetClientRect(parent, &parent_rect);
|
||||
|
||||
x = parent_rect.left;
|
||||
y = parent_rect.top;
|
||||
|
||||
/* FIXME: we should be able to early out if nothing */
|
||||
/* has changed with nWidth != parent_rect width */
|
||||
TRACE("nRows: %d, infoPtr->nButtonHeight: %d\n", infoPtr->nRows, infoPtr->nButtonHeight);
|
||||
|
||||
if (infoPtr->dwStyle & CCS_NORESIZE) {
|
||||
uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
|
||||
cx = 0;
|
||||
cy = 0;
|
||||
TOOLBAR_CalcToolbar (hwnd);
|
||||
cy = TOP_BORDER + infoPtr->nRows * infoPtr->nButtonHeight + BOTTOM_BORDER;
|
||||
cx = parent_rect.right - parent_rect.left;
|
||||
|
||||
if ((infoPtr->dwStyle & TBSTYLE_WRAPABLE) || (infoPtr->dwExStyle & TBSTYLE_EX_UNDOC1))
|
||||
{
|
||||
TOOLBAR_CalcToolbar(hwnd);
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
}
|
||||
else {
|
||||
infoPtr->nWidth = parent_rect.right - parent_rect.left;
|
||||
TOOLBAR_CalcToolbar (hwnd);
|
||||
InvalidateRect( hwnd, NULL, TRUE );
|
||||
cy = infoPtr->nHeight;
|
||||
cx = infoPtr->nWidth;
|
||||
|
||||
if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_NOMOVEY) {
|
||||
GetWindowRect(hwnd, &window_rect);
|
||||
ScreenToClient(parent, (LPPOINT)&window_rect.left);
|
||||
y = window_rect.top;
|
||||
}
|
||||
if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_BOTTOM) {
|
||||
if (!(infoPtr->dwStyle & CCS_NORESIZE))
|
||||
{
|
||||
RECT window_rect;
|
||||
UINT uPosFlags = SWP_NOZORDER;
|
||||
|
||||
if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_NOMOVEY)
|
||||
{
|
||||
GetWindowRect(hwnd, &window_rect);
|
||||
ScreenToClient(parent, (LPPOINT)&window_rect.left);
|
||||
y = window_rect.top;
|
||||
}
|
||||
if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_BOTTOM)
|
||||
{
|
||||
GetWindowRect(hwnd, &window_rect);
|
||||
y = parent_rect.bottom - ( window_rect.bottom - window_rect.top);
|
||||
}
|
||||
|
||||
if (infoPtr->dwStyle & CCS_NOPARENTALIGN)
|
||||
uPosFlags |= SWP_NOMOVE;
|
||||
|
||||
if (!(infoPtr->dwStyle & CCS_NODIVIDER))
|
||||
cy += GetSystemMetrics(SM_CYEDGE);
|
||||
|
||||
if (infoPtr->dwStyle & WS_BORDER)
|
||||
{
|
||||
x = y = 1; /* FIXME: this looks wrong */
|
||||
cy += GetSystemMetrics(SM_CYEDGE);
|
||||
cx += GetSystemMetrics(SM_CXEDGE);
|
||||
}
|
||||
|
||||
SetWindowPos(hwnd, NULL, x, y, cx, cy, uPosFlags);
|
||||
}
|
||||
|
||||
if (infoPtr->dwStyle & CCS_NOPARENTALIGN)
|
||||
uPosFlags |= SWP_NOMOVE;
|
||||
|
||||
if (!(infoPtr->dwStyle & CCS_NODIVIDER))
|
||||
cy += GetSystemMetrics(SM_CYEDGE);
|
||||
|
||||
if (infoPtr->dwStyle & WS_BORDER)
|
||||
{
|
||||
x = y = 1;
|
||||
cy += GetSystemMetrics(SM_CYEDGE);
|
||||
cx += GetSystemMetrics(SM_CXEDGE);
|
||||
}
|
||||
|
||||
infoPtr->bAutoSize = TRUE;
|
||||
SetWindowPos (hwnd, HWND_TOP, x, y, cx, cy, uPosFlags);
|
||||
/* The following line makes sure that the infoPtr->bAutoSize is turned off
|
||||
* after the setwindowpos calls */
|
||||
infoPtr->bAutoSize = FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3985,6 +3956,7 @@ TOOLBAR_InsertButtonA (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
Free (oldButtons);
|
||||
|
||||
TOOLBAR_CalcToolbar (hwnd);
|
||||
TOOLBAR_AutoSize (hwnd);
|
||||
|
||||
InvalidateRect (hwnd, NULL, TRUE);
|
||||
|
||||
|
@ -4085,6 +4057,7 @@ TOOLBAR_InsertButtonW (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
Free (oldButtons);
|
||||
|
||||
TOOLBAR_CalcToolbar (hwnd);
|
||||
TOOLBAR_AutoSize (hwnd);
|
||||
|
||||
InvalidateRect (hwnd, NULL, TRUE);
|
||||
|
||||
|
@ -4330,6 +4303,7 @@ TOOLBAR_MoveButton (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
|
||||
TOOLBAR_CalcToolbar(hwnd);
|
||||
TOOLBAR_AutoSize(hwnd);
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
|
||||
return TRUE;
|
||||
|
@ -4369,6 +4343,7 @@ TOOLBAR_ReplaceBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
|
||||
LPTBREPLACEBITMAP lpReplace = (LPTBREPLACEBITMAP) lParam;
|
||||
HBITMAP hBitmap;
|
||||
HBITMAP hbmLoad = NULL;
|
||||
int i = 0, nOldButtons = 0, pos = 0;
|
||||
int nOldBitmaps, nNewBitmaps = 0;
|
||||
HIMAGELIST himlDef = 0;
|
||||
|
@ -4383,9 +4358,12 @@ TOOLBAR_ReplaceBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
return FALSE;
|
||||
}
|
||||
else if (lpReplace->hInstOld != 0)
|
||||
{
|
||||
FIXME("resources not in the current module not implemented\n");
|
||||
return FALSE;
|
||||
|
||||
if (lpReplace->hInstNew)
|
||||
{
|
||||
hbmLoad = LoadBitmapW(lpReplace->hInstNew,(LPWSTR)lpReplace->nIDNew);
|
||||
hBitmap = hbmLoad;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4412,6 +4390,8 @@ TOOLBAR_ReplaceBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
if (nOldButtons == 0)
|
||||
{
|
||||
WARN("No hinst/bitmap found! hInst %p nID %x\n", lpReplace->hInstOld, lpReplace->nIDOld);
|
||||
if (hbmLoad)
|
||||
DeleteObject (hbmLoad);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -4463,6 +4443,8 @@ TOOLBAR_ReplaceBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
|
||||
if (hbmLoad)
|
||||
DeleteObject (hbmLoad);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -4864,12 +4846,6 @@ TOOLBAR_SetButtonWidth (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
infoPtr->cxMin = (INT)LOWORD(lParam);
|
||||
infoPtr->cxMax = (INT)HIWORD(lParam);
|
||||
|
||||
/* if both values are 0 then we are done */
|
||||
if (lParam == 0) {
|
||||
TRACE("setting both min and max to 0, norecalc\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* otherwise we need to recalc the toolbar and in some cases
|
||||
recalc the bounding rectangle (does DrawText w/ DT_CALCRECT
|
||||
which doesn't actually draw - GA). */
|
||||
|
@ -5530,7 +5506,6 @@ TOOLBAR_Unkwn463 (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
case 1:
|
||||
lpsize->cy = infoPtr->rcBound.bottom - infoPtr->rcBound.top;
|
||||
/* lpsize->cy = infoPtr->nHeight; */
|
||||
break;
|
||||
default:
|
||||
ERR("Unknown wParam %d for Toolbar message [0463]. Please report\n",
|
||||
|
@ -5566,7 +5541,6 @@ TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
infoPtr->nBitmapHeight = 15;
|
||||
infoPtr->nBitmapWidth = 16;
|
||||
|
||||
infoPtr->nHeight = infoPtr->nButtonHeight + TOP_BORDER + BOTTOM_BORDER;
|
||||
infoPtr->nMaxTextRows = 1;
|
||||
infoPtr->cxMin = -1;
|
||||
infoPtr->cxMax = -1;
|
||||
|
@ -5579,7 +5553,6 @@ TOOLBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
infoPtr->nOldHit = -1;
|
||||
infoPtr->nHotItem = -1;
|
||||
infoPtr->hwndNotify = ((LPCREATESTRUCTW)lParam)->hwndParent;
|
||||
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 */
|
||||
infoPtr->bDragOutSent = FALSE;
|
||||
|
@ -6641,131 +6614,50 @@ static LRESULT
|
|||
TOOLBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
|
||||
DWORD dwStyle = infoPtr->dwStyle;
|
||||
RECT parent_rect;
|
||||
RECT window_rect;
|
||||
HWND parent;
|
||||
INT x, y;
|
||||
INT cx, cy;
|
||||
INT flags;
|
||||
UINT uPosFlags = 0;
|
||||
|
||||
/* Resize deadlock check */
|
||||
if (infoPtr->bAutoSize) {
|
||||
infoPtr->bAutoSize = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: optimize to only update size if the new size doesn't */
|
||||
/* match the current size */
|
||||
|
||||
flags = (INT) wParam;
|
||||
|
||||
/* FIXME for flags =
|
||||
* SIZE_MAXIMIZED, SIZE_MAXSHOW, SIZE_MINIMIZED
|
||||
*/
|
||||
|
||||
TRACE("sizing toolbar!\n");
|
||||
|
||||
if (flags == SIZE_RESTORED) {
|
||||
/* width and height don't apply */
|
||||
parent = GetParent (hwnd);
|
||||
GetClientRect(parent, &parent_rect);
|
||||
x = parent_rect.left;
|
||||
y = parent_rect.top;
|
||||
if (infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
|
||||
{
|
||||
RECT delta_width, delta_height, client, dummy;
|
||||
DWORD min_x, max_x, min_y, max_y;
|
||||
TBUTTON_INFO *btnPtr;
|
||||
INT i;
|
||||
|
||||
if (dwStyle & CCS_NORESIZE) {
|
||||
uPosFlags |= (SWP_NOSIZE | SWP_NOMOVE);
|
||||
|
||||
/*
|
||||
* this sets the working width of the toolbar, and
|
||||
* Calc Toolbar will not adjust it, only the height
|
||||
*/
|
||||
infoPtr->nWidth = parent_rect.right - parent_rect.left;
|
||||
cy = infoPtr->nHeight;
|
||||
cx = infoPtr->nWidth;
|
||||
TOOLBAR_CalcToolbar (hwnd);
|
||||
infoPtr->nWidth = cx;
|
||||
infoPtr->nHeight = cy;
|
||||
}
|
||||
else {
|
||||
infoPtr->nWidth = parent_rect.right - parent_rect.left;
|
||||
TOOLBAR_CalcToolbar (hwnd);
|
||||
cy = infoPtr->nHeight;
|
||||
cx = infoPtr->nWidth;
|
||||
|
||||
if ((dwStyle & CCS_BOTTOM) == CCS_NOMOVEY) {
|
||||
GetWindowRect(hwnd, &window_rect);
|
||||
ScreenToClient(parent, (LPPOINT)&window_rect.left);
|
||||
y = window_rect.top;
|
||||
}
|
||||
if ((dwStyle & CCS_BOTTOM) == CCS_BOTTOM) {
|
||||
GetWindowRect(hwnd, &window_rect);
|
||||
y = parent_rect.bottom -
|
||||
( window_rect.bottom - window_rect.top);
|
||||
}
|
||||
}
|
||||
|
||||
if (dwStyle & CCS_NOPARENTALIGN) {
|
||||
uPosFlags |= SWP_NOMOVE;
|
||||
cy = infoPtr->nHeight;
|
||||
cx = infoPtr->nWidth;
|
||||
}
|
||||
|
||||
if (!(dwStyle & CCS_NODIVIDER))
|
||||
cy += GetSystemMetrics(SM_CYEDGE);
|
||||
|
||||
if (dwStyle & WS_BORDER)
|
||||
{
|
||||
x = y = 1;
|
||||
cy += GetSystemMetrics(SM_CYEDGE);
|
||||
cx += GetSystemMetrics(SM_CXEDGE);
|
||||
}
|
||||
|
||||
if(infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
|
||||
GetClientRect(hwnd, &client);
|
||||
if(client.right > infoPtr->client_rect.right)
|
||||
{
|
||||
RECT delta_width, delta_height, client, dummy;
|
||||
DWORD min_x, max_x, min_y, max_y;
|
||||
TBUTTON_INFO *btnPtr;
|
||||
INT i;
|
||||
|
||||
GetClientRect(hwnd, &client);
|
||||
if(client.right > infoPtr->client_rect.right)
|
||||
{
|
||||
min_x = infoPtr->client_rect.right;
|
||||
max_x = client.right;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_x = infoPtr->client_rect.right;
|
||||
min_x = client.right;
|
||||
}
|
||||
if(client.bottom > infoPtr->client_rect.bottom)
|
||||
{
|
||||
min_y = infoPtr->client_rect.bottom;
|
||||
max_y = client.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_y = infoPtr->client_rect.bottom;
|
||||
min_y = client.bottom;
|
||||
}
|
||||
|
||||
SetRect(&delta_width, min_x, 0, max_x, min_y);
|
||||
SetRect(&delta_height, 0, min_y, max_x, max_y);
|
||||
|
||||
TRACE("delta_width %s delta_height %s\n", wine_dbgstr_rect(&delta_width), wine_dbgstr_rect(&delta_height));
|
||||
btnPtr = infoPtr->buttons;
|
||||
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
|
||||
if(IntersectRect(&dummy, &delta_width, &btnPtr->rect) ||
|
||||
IntersectRect(&dummy, &delta_height, &btnPtr->rect))
|
||||
InvalidateRect(hwnd, &btnPtr->rect, TRUE);
|
||||
min_x = infoPtr->client_rect.right;
|
||||
max_x = client.right;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_x = infoPtr->client_rect.right;
|
||||
min_x = client.right;
|
||||
}
|
||||
if(client.bottom > infoPtr->client_rect.bottom)
|
||||
{
|
||||
min_y = infoPtr->client_rect.bottom;
|
||||
max_y = client.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_y = infoPtr->client_rect.bottom;
|
||||
min_y = client.bottom;
|
||||
}
|
||||
|
||||
if((uPosFlags & (SWP_NOSIZE | SWP_NOMOVE)) != (SWP_NOSIZE | SWP_NOMOVE))
|
||||
SetWindowPos (hwnd, 0, x, y, cx, cy, uPosFlags | SWP_NOZORDER);
|
||||
SetRect(&delta_width, min_x, 0, max_x, min_y);
|
||||
SetRect(&delta_height, 0, min_y, max_x, max_y);
|
||||
|
||||
TRACE("delta_width %s delta_height %s\n", wine_dbgstr_rect(&delta_width), wine_dbgstr_rect(&delta_height));
|
||||
btnPtr = infoPtr->buttons;
|
||||
for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
|
||||
if(IntersectRect(&dummy, &delta_width, &btnPtr->rect) ||
|
||||
IntersectRect(&dummy, &delta_height, &btnPtr->rect))
|
||||
InvalidateRect(hwnd, &btnPtr->rect, TRUE);
|
||||
}
|
||||
GetClientRect(hwnd, &infoPtr->client_rect);
|
||||
TOOLBAR_AutoSize(hwnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6782,8 +6674,6 @@ TOOLBAR_StyleChanged (HWND hwnd, INT nType, LPSTYLESTRUCT lpStyle)
|
|||
else
|
||||
infoPtr->dwDTFlags = DT_CENTER | DT_END_ELLIPSIS;
|
||||
|
||||
infoPtr->bBtnTranspnt = (lpStyle->styleNew &
|
||||
(TBSTYLE_FLAT | TBSTYLE_LIST));
|
||||
TOOLBAR_CheckStyle (hwnd, lpStyle->styleNew);
|
||||
|
||||
TRACE("new style 0x%08lx\n", lpStyle->styleNew);
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "winnls.h"
|
||||
#include "commctrl.h"
|
||||
#include "comctl32.h"
|
||||
#include "uxtheme.h"
|
||||
#include "tmschema.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -75,7 +77,8 @@ typedef struct
|
|||
#define DEFAULT_ADDBOT 0 /* amount to extend below the buddy window */
|
||||
#define DEFAULT_BUDDYBORDER 2 /* Width/height of the buddy border */
|
||||
#define DEFAULT_BUDDYSPACER 2 /* Spacer between the buddy and the ctrl */
|
||||
|
||||
#define DEFAULT_BUDDYBORDER_THEMED 1 /* buddy border when theming is enabled */
|
||||
#define DEFAULT_BUDDYSPACER_THEMED 0 /* buddy spacer when theming is enabled */
|
||||
|
||||
/* Work constants */
|
||||
|
||||
|
@ -175,6 +178,9 @@ static BOOL UPDOWN_HasBuddyBorder(UPDOWN_INFO* infoPtr)
|
|||
*/
|
||||
static void UPDOWN_GetArrowRect (UPDOWN_INFO* infoPtr, RECT *rect, int arrow)
|
||||
{
|
||||
HTHEME theme = GetWindowTheme (infoPtr->Self);
|
||||
const int border = theme ? DEFAULT_BUDDYBORDER_THEMED : DEFAULT_BUDDYBORDER;
|
||||
const int spacer = theme ? DEFAULT_BUDDYSPACER_THEMED : DEFAULT_BUDDYSPACER;
|
||||
GetClientRect (infoPtr->Self, rect);
|
||||
|
||||
/*
|
||||
|
@ -183,17 +189,17 @@ static void UPDOWN_GetArrowRect (UPDOWN_INFO* infoPtr, RECT *rect, int arrow)
|
|||
*/
|
||||
if (UPDOWN_HasBuddyBorder(infoPtr)) {
|
||||
if (infoPtr->dwStyle & UDS_ALIGNLEFT)
|
||||
rect->left += DEFAULT_BUDDYBORDER;
|
||||
rect->left += border;
|
||||
else
|
||||
rect->right -= DEFAULT_BUDDYBORDER;
|
||||
rect->right -= border;
|
||||
|
||||
InflateRect(rect, 0, -DEFAULT_BUDDYBORDER);
|
||||
InflateRect(rect, 0, -border);
|
||||
}
|
||||
|
||||
/* now figure out if we need a space away from the buddy */
|
||||
if ( IsWindow(infoPtr->Buddy) ) {
|
||||
if (infoPtr->dwStyle & UDS_ALIGNLEFT) rect->right -= DEFAULT_BUDDYSPACER;
|
||||
else rect->left += DEFAULT_BUDDYSPACER;
|
||||
if (IsWindow(infoPtr->Buddy) ) {
|
||||
if (infoPtr->dwStyle & UDS_ALIGNLEFT) rect->right -= spacer;
|
||||
else rect->left += spacer;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -206,11 +212,11 @@ static void UPDOWN_GetArrowRect (UPDOWN_INFO* infoPtr, RECT *rect, int arrow)
|
|||
if (arrow & FLAG_INCR)
|
||||
rect->left = rect->left + len/2;
|
||||
if (arrow & FLAG_DECR)
|
||||
rect->right = rect->left + len/2 - 1;
|
||||
rect->right = rect->left + len/2 - (theme ? 0 : 1);
|
||||
} else {
|
||||
int len = rect->bottom - rect->top + 1; /* compute the height */
|
||||
if (arrow & FLAG_INCR)
|
||||
rect->bottom = rect->top + len/2 - 1;
|
||||
rect->bottom = rect->top + len/2 - (theme ? 0 : 1);
|
||||
if (arrow & FLAG_DECR)
|
||||
rect->top = rect->top + len/2;
|
||||
}
|
||||
|
@ -219,10 +225,10 @@ static void UPDOWN_GetArrowRect (UPDOWN_INFO* infoPtr, RECT *rect, int arrow)
|
|||
/***********************************************************************
|
||||
* UPDOWN_GetArrowFromPoint
|
||||
* Returns the rectagle (for the up or down arrow) that contains pt.
|
||||
* If it returns the up rect, it returns TRUE.
|
||||
* If it returns the down rect, it returns FALSE.
|
||||
* If it returns the up rect, it returns FLAG_INCR.
|
||||
* If it returns the down rect, it returns FLAG_DECR.
|
||||
*/
|
||||
static BOOL UPDOWN_GetArrowFromPoint (UPDOWN_INFO* infoPtr, RECT *rect, POINT pt)
|
||||
static INT UPDOWN_GetArrowFromPoint (UPDOWN_INFO* infoPtr, RECT *rect, POINT pt)
|
||||
{
|
||||
UPDOWN_GetArrowRect (infoPtr, rect, FLAG_INCR);
|
||||
if(PtInRect(rect, pt)) return FLAG_INCR;
|
||||
|
@ -341,6 +347,24 @@ static BOOL UPDOWN_SetBuddyInt (UPDOWN_INFO *infoPtr)
|
|||
return SetWindowTextW(infoPtr->Buddy, txt);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* UPDOWN_DrawBuddyBackground
|
||||
*
|
||||
* Draw buddy background for visual integration.
|
||||
*/
|
||||
static BOOL UPDOWN_DrawBuddyBackground (UPDOWN_INFO *infoPtr, HDC hdc)
|
||||
{
|
||||
RECT br;
|
||||
HTHEME buddyTheme = GetWindowTheme (infoPtr->Buddy);
|
||||
if (!buddyTheme) return FALSE;
|
||||
|
||||
GetClientRect (infoPtr->Buddy, &br);
|
||||
MapWindowPoints (infoPtr->Buddy, infoPtr->Self, (POINT*)&br, 2);
|
||||
/* FIXME: take disabled etc. into account */
|
||||
DrawThemeBackground (buddyTheme, hdc, 0, 0, &br, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* UPDOWN_Draw
|
||||
*
|
||||
|
@ -348,36 +372,61 @@ static BOOL UPDOWN_SetBuddyInt (UPDOWN_INFO *infoPtr)
|
|||
*/
|
||||
static LRESULT UPDOWN_Draw (UPDOWN_INFO *infoPtr, HDC hdc)
|
||||
{
|
||||
BOOL pressed, hot;
|
||||
BOOL uPressed, uHot, dPressed, dHot;
|
||||
RECT rect;
|
||||
HTHEME theme = GetWindowTheme (infoPtr->Self);
|
||||
int uPart = 0, uState = 0, dPart = 0, dState = 0;
|
||||
BOOL needBuddyBg = FALSE;
|
||||
|
||||
uPressed = (infoPtr->Flags & FLAG_PRESSED) && (infoPtr->Flags & FLAG_INCR);
|
||||
uHot = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
|
||||
dPressed = (infoPtr->Flags & FLAG_PRESSED) && (infoPtr->Flags & FLAG_DECR);
|
||||
dHot = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN);
|
||||
if (theme) {
|
||||
uPart = (infoPtr->dwStyle & UDS_HORZ) ? SPNP_UPHORZ : SPNP_UP;
|
||||
uState = (infoPtr->dwStyle & WS_DISABLED) ? DNS_DISABLED
|
||||
: (uPressed ? DNS_PRESSED : (uHot ? DNS_HOT : DNS_NORMAL));
|
||||
dPart = (infoPtr->dwStyle & UDS_HORZ) ? SPNP_DOWNHORZ : SPNP_DOWN;
|
||||
dState = (infoPtr->dwStyle & WS_DISABLED) ? DNS_DISABLED
|
||||
: (dPressed ? DNS_PRESSED : (dHot ? DNS_HOT : DNS_NORMAL));
|
||||
needBuddyBg = IsWindow (infoPtr->Buddy)
|
||||
&& (IsThemeBackgroundPartiallyTransparent (theme, uPart, uState)
|
||||
|| IsThemeBackgroundPartiallyTransparent (theme, dPart, dState));
|
||||
}
|
||||
|
||||
/* Draw the common border between ourselves and our buddy */
|
||||
if (UPDOWN_HasBuddyBorder(infoPtr)) {
|
||||
GetClientRect(infoPtr->Self, &rect);
|
||||
DrawEdge(hdc, &rect, EDGE_SUNKEN,
|
||||
BF_BOTTOM | BF_TOP |
|
||||
(infoPtr->dwStyle & UDS_ALIGNLEFT ? BF_LEFT : BF_RIGHT));
|
||||
if (UPDOWN_HasBuddyBorder(infoPtr) || needBuddyBg) {
|
||||
if (!theme || !UPDOWN_DrawBuddyBackground (infoPtr, hdc)) {
|
||||
GetClientRect(infoPtr->Self, &rect);
|
||||
DrawEdge(hdc, &rect, EDGE_SUNKEN,
|
||||
BF_BOTTOM | BF_TOP |
|
||||
(infoPtr->dwStyle & UDS_ALIGNLEFT ? BF_LEFT : BF_RIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw the incr button */
|
||||
UPDOWN_GetArrowRect (infoPtr, &rect, FLAG_INCR);
|
||||
pressed = (infoPtr->Flags & FLAG_PRESSED) && (infoPtr->Flags & FLAG_INCR);
|
||||
hot = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
|
||||
DrawFrameControl(hdc, &rect, DFC_SCROLL,
|
||||
(infoPtr->dwStyle & UDS_HORZ ? DFCS_SCROLLRIGHT : DFCS_SCROLLUP) |
|
||||
((infoPtr->dwStyle & UDS_HOTTRACK) && hot ? DFCS_HOT : 0) |
|
||||
(pressed ? DFCS_PUSHED : 0) |
|
||||
(infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
|
||||
if (theme) {
|
||||
DrawThemeBackground(theme, hdc, uPart, uState, &rect, NULL);
|
||||
} else {
|
||||
DrawFrameControl(hdc, &rect, DFC_SCROLL,
|
||||
(infoPtr->dwStyle & UDS_HORZ ? DFCS_SCROLLRIGHT : DFCS_SCROLLUP) |
|
||||
((infoPtr->dwStyle & UDS_HOTTRACK) && uHot ? DFCS_HOT : 0) |
|
||||
(uPressed ? DFCS_PUSHED : 0) |
|
||||
(infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
|
||||
}
|
||||
|
||||
/* Draw the decr button */
|
||||
UPDOWN_GetArrowRect(infoPtr, &rect, FLAG_DECR);
|
||||
pressed = (infoPtr->Flags & FLAG_PRESSED) && (infoPtr->Flags & FLAG_DECR);
|
||||
hot = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN);
|
||||
DrawFrameControl(hdc, &rect, DFC_SCROLL,
|
||||
(infoPtr->dwStyle & UDS_HORZ ? DFCS_SCROLLLEFT : DFCS_SCROLLDOWN) |
|
||||
((infoPtr->dwStyle & UDS_HOTTRACK) && hot ? DFCS_HOT : 0) |
|
||||
(pressed ? DFCS_PUSHED : 0) |
|
||||
(infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
|
||||
if (theme) {
|
||||
DrawThemeBackground(theme, hdc, dPart, dState, &rect, NULL);
|
||||
} else {
|
||||
DrawFrameControl(hdc, &rect, DFC_SCROLL,
|
||||
(infoPtr->dwStyle & UDS_HORZ ? DFCS_SCROLLLEFT : DFCS_SCROLLDOWN) |
|
||||
((infoPtr->dwStyle & UDS_HOTTRACK) && dHot ? DFCS_HOT : 0) |
|
||||
(dPressed ? DFCS_PUSHED : 0) |
|
||||
(infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -653,6 +702,7 @@ static void UPDOWN_HandleMouseEvent (UPDOWN_INFO *infoPtr, UINT msg, INT x, INT
|
|||
POINT pt = { x, y };
|
||||
RECT rect;
|
||||
int temp, arrow;
|
||||
TRACKMOUSEEVENT tme;
|
||||
|
||||
TRACE("msg %04x point %s\n", msg, wine_dbgstr_point(&pt));
|
||||
|
||||
|
@ -713,7 +763,19 @@ static void UPDOWN_HandleMouseEvent (UPDOWN_INFO *infoPtr, UINT msg, INT x, INT
|
|||
|
||||
/* If state changed, redraw the control */
|
||||
if(temp != infoPtr->Flags)
|
||||
InvalidateRect (infoPtr->Self, &rect, FALSE);
|
||||
InvalidateRect (infoPtr->Self, NULL, FALSE);
|
||||
|
||||
/* Set up tracking so the mousein flags can be reset when the
|
||||
* mouse leaves the control */
|
||||
tme.cbSize = sizeof( tme );
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = infoPtr->Self;
|
||||
TrackMouseEvent (&tme);
|
||||
|
||||
break;
|
||||
case WM_MOUSELEAVE:
|
||||
infoPtr->Flags &= ~(FLAG_MOUSEIN | FLAG_ARROW);
|
||||
InvalidateRect (infoPtr->Self, NULL, FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -729,6 +791,8 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
|
|||
{
|
||||
UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr (hwnd);
|
||||
int temp;
|
||||
static const WCHAR themeClass[] = {'S','p','i','n',0};
|
||||
HTHEME theme;
|
||||
|
||||
TRACE("hwnd=%p msg=%04x wparam=%08x lparam=%08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
|
@ -761,6 +825,8 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
|
|||
if (infoPtr->dwStyle & UDS_AUTOBUDDY)
|
||||
UPDOWN_SetBuddy (infoPtr, GetWindow (hwnd, GW_HWNDPREV));
|
||||
|
||||
OpenThemeData (hwnd, themeClass);
|
||||
|
||||
TRACE("UpDown Ctrl creation, hwnd=%p\n", hwnd);
|
||||
break;
|
||||
|
||||
|
@ -771,6 +837,8 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
|
|||
|
||||
Free (infoPtr);
|
||||
SetWindowLongPtrW (hwnd, 0, 0);
|
||||
theme = GetWindowTheme (hwnd);
|
||||
CloseThemeData (theme);
|
||||
TRACE("UpDown Ctrl destruction, hwnd=%p\n", hwnd);
|
||||
break;
|
||||
|
||||
|
@ -791,6 +859,13 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
|
|||
}
|
||||
break;
|
||||
|
||||
case WM_THEMECHANGED:
|
||||
theme = GetWindowTheme (hwnd);
|
||||
CloseThemeData (theme);
|
||||
OpenThemeData (hwnd, themeClass);
|
||||
InvalidateRect (hwnd, NULL, FALSE);
|
||||
break;
|
||||
|
||||
case WM_TIMER:
|
||||
/* is this the auto-press timer? */
|
||||
if(wParam == TIMER_AUTOPRESS) {
|
||||
|
@ -849,6 +924,7 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
|
|||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_MOUSELEAVE:
|
||||
if(UPDOWN_IsEnabled(infoPtr))
|
||||
UPDOWN_HandleMouseEvent (infoPtr, message, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue