mirror of
https://github.com/reactos/reactos.git
synced 2024-08-19 09:59:44 +00:00
[comctl32]
- Sync comctl32 with wine. Among it's improvements are reduced flicker in the listview and hot tracking support for themed buttons svn path=/branches/GSoC_2011/ThemesSupport/; revision=52714
This commit is contained in:
parent
84291d0d72
commit
8d084e9377
|
@ -1120,10 +1120,10 @@ static LRESULT COMBOEX_Command (COMBOEX_INFO *infoPtr, WPARAM wParam)
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case CBN_DROPDOWN:
|
case CBN_DROPDOWN:
|
||||||
SetFocus (infoPtr->hwndCombo);
|
SetFocus (infoPtr->hwndCombo);
|
||||||
ShowWindow (infoPtr->hwndEdit, SW_HIDE);
|
ShowWindow (infoPtr->hwndEdit, SW_HIDE);
|
||||||
return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
|
infoPtr->flags |= WCBE_ACTEDIT;
|
||||||
|
return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
|
||||||
case CBN_CLOSEUP:
|
case CBN_CLOSEUP:
|
||||||
SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
|
SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
|
||||||
/*
|
/*
|
||||||
|
@ -1741,7 +1741,7 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
|
||||||
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
|
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
|
||||||
|
|
||||||
case WM_KEYDOWN: {
|
case WM_KEYDOWN: {
|
||||||
INT_PTR oldItem, selected, step = 1;
|
INT_PTR oldItem, selected;
|
||||||
CBE_ITEMDATA *item;
|
CBE_ITEMDATA *item;
|
||||||
|
|
||||||
switch ((INT)wParam)
|
switch ((INT)wParam)
|
||||||
|
@ -1851,13 +1851,15 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VK_UP:
|
case VK_UP:
|
||||||
step = -1;
|
|
||||||
case VK_DOWN:
|
case VK_DOWN:
|
||||||
/* by default, step is 1 */
|
{
|
||||||
|
INT step = wParam == VK_DOWN ? 1 : -1;
|
||||||
|
|
||||||
oldItem = SendMessageW (infoPtr->hwndSelf, CB_GETCURSEL, 0, 0);
|
oldItem = SendMessageW (infoPtr->hwndSelf, CB_GETCURSEL, 0, 0);
|
||||||
if (oldItem >= 0 && oldItem + step >= 0)
|
if (oldItem >= 0 && oldItem + step >= 0)
|
||||||
SendMessageW (infoPtr->hwndSelf, CB_SETCURSEL, oldItem + step, 0);
|
SendMessageW (infoPtr->hwndSelf, CB_SETCURSEL, oldItem + step, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
|
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,23 +168,23 @@ DWORD WINAPI GetSize (LPVOID lpMem)
|
||||||
*|typedef INT (CALLBACK *MRUStringCmpFn)(LPCTSTR lhs, LPCTSTR rhs);
|
*|typedef INT (CALLBACK *MRUStringCmpFn)(LPCTSTR lhs, LPCTSTR rhs);
|
||||||
*|typedef INT (CALLBACK *MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length);
|
*|typedef INT (CALLBACK *MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length);
|
||||||
*|
|
*|
|
||||||
*|typedef struct tagCREATEMRULIST
|
*|typedef struct tagMRUINFO
|
||||||
*|{
|
*|{
|
||||||
*| DWORD cbSize;
|
*| DWORD cbSize;
|
||||||
*| DWORD nMaxItems;
|
*| UINT uMax;
|
||||||
*| DWORD dwFlags;
|
*| UINT fFlags;
|
||||||
*| HKEY hKey;
|
*| HKEY hKey;
|
||||||
*| LPTSTR lpszSubKey;
|
*| LPTSTR lpszSubKey;
|
||||||
*| PROC lpfnCompare;
|
*| PROC lpfnCompare;
|
||||||
*|} CREATEMRULIST, *LPCREATEMRULIST;
|
*|} MRUINFO, *LPMRUINFO;
|
||||||
*
|
*
|
||||||
* MEMBERS
|
* MEMBERS
|
||||||
* cbSize [I] The size of the CREATEMRULIST structure. This must be set
|
* cbSize [I] The size of the MRUINFO structure. This must be set
|
||||||
* to sizeof(CREATEMRULIST) by the caller.
|
* to sizeof(MRUINFO) by the caller.
|
||||||
* nMaxItems [I] The maximum number of items allowed in the list. Because
|
* uMax [I] The maximum number of items allowed in the list. Because
|
||||||
* of the limited number of identifiers, this should be set to
|
* of the limited number of identifiers, this should be set to
|
||||||
* a value from 1 to 30 by the caller.
|
* a value from 1 to 30 by the caller.
|
||||||
* dwFlags [I] If bit 0 is set, the list will be used to store binary
|
* fFlags [I] If bit 0 is set, the list will be used to store binary
|
||||||
* data, otherwise it is assumed to store strings. If bit 1
|
* data, otherwise it is assumed to store strings. If bit 1
|
||||||
* is set, every change made to the list will be reflected in
|
* is set, every change made to the list will be reflected in
|
||||||
* the registry immediately, otherwise changes will only be
|
* the registry immediately, otherwise changes will only be
|
||||||
|
@ -210,11 +210,11 @@ typedef INT (CALLBACK *MRUStringCmpFnA)(LPCSTR lhs, LPCSTR rhs);
|
||||||
typedef INT (CALLBACK *MRUStringCmpFnW)(LPCWSTR lhs, LPCWSTR rhs);
|
typedef INT (CALLBACK *MRUStringCmpFnW)(LPCWSTR lhs, LPCWSTR rhs);
|
||||||
typedef INT (CALLBACK *MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length);
|
typedef INT (CALLBACK *MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length);
|
||||||
|
|
||||||
typedef struct tagCREATEMRULISTA
|
typedef struct tagMRUINFOA
|
||||||
{
|
{
|
||||||
DWORD cbSize;
|
DWORD cbSize;
|
||||||
DWORD nMaxItems;
|
UINT uMax;
|
||||||
DWORD dwFlags;
|
UINT fFlags;
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
LPSTR lpszSubKey;
|
LPSTR lpszSubKey;
|
||||||
union
|
union
|
||||||
|
@ -222,13 +222,13 @@ typedef struct tagCREATEMRULISTA
|
||||||
MRUStringCmpFnA string_cmpfn;
|
MRUStringCmpFnA string_cmpfn;
|
||||||
MRUBinaryCmpFn binary_cmpfn;
|
MRUBinaryCmpFn binary_cmpfn;
|
||||||
} u;
|
} u;
|
||||||
} CREATEMRULISTA, *LPCREATEMRULISTA;
|
} MRUINFOA, *LPMRUINFOA;
|
||||||
|
|
||||||
typedef struct tagCREATEMRULISTW
|
typedef struct tagMRUINFOW
|
||||||
{
|
{
|
||||||
DWORD cbSize;
|
DWORD cbSize;
|
||||||
DWORD nMaxItems;
|
UINT uMax;
|
||||||
DWORD dwFlags;
|
UINT fFlags;
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
LPWSTR lpszSubKey;
|
LPWSTR lpszSubKey;
|
||||||
union
|
union
|
||||||
|
@ -236,12 +236,12 @@ typedef struct tagCREATEMRULISTW
|
||||||
MRUStringCmpFnW string_cmpfn;
|
MRUStringCmpFnW string_cmpfn;
|
||||||
MRUBinaryCmpFn binary_cmpfn;
|
MRUBinaryCmpFn binary_cmpfn;
|
||||||
} u;
|
} u;
|
||||||
} CREATEMRULISTW, *LPCREATEMRULISTW;
|
} MRUINFOW, *LPMRUINFOW;
|
||||||
|
|
||||||
/* dwFlags */
|
/* MRUINFO.fFlags */
|
||||||
#define MRUF_STRING_LIST 0 /* list will contain strings */
|
#define MRU_STRING 0 /* list will contain strings */
|
||||||
#define MRUF_BINARY_LIST 1 /* list will contain binary data */
|
#define MRU_BINARY 1 /* list will contain binary data */
|
||||||
#define MRUF_DELAYED_SAVE 2 /* only save list order to reg. is FreeMRUList */
|
#define MRU_CACHEWRITE 2 /* only save list order to reg. is FreeMRUList */
|
||||||
|
|
||||||
/* If list is a string list lpfnCompare has the following prototype
|
/* If list is a string list lpfnCompare has the following prototype
|
||||||
* int CALLBACK MRUCompareString(LPCSTR s1, LPCSTR s2)
|
* int CALLBACK MRUCompareString(LPCSTR s1, LPCSTR s2)
|
||||||
|
@ -263,7 +263,7 @@ typedef struct tagWINEMRUITEM
|
||||||
|
|
||||||
typedef struct tagWINEMRULIST
|
typedef struct tagWINEMRULIST
|
||||||
{
|
{
|
||||||
CREATEMRULISTW extview; /* original create information */
|
MRUINFOW extview; /* original create information */
|
||||||
BOOL isUnicode; /* is compare fn Unicode */
|
BOOL isUnicode; /* is compare fn Unicode */
|
||||||
DWORD wineFlags; /* internal flags */
|
DWORD wineFlags; /* internal flags */
|
||||||
DWORD cursize; /* current size of realMRU */
|
DWORD cursize; /* current size of realMRU */
|
||||||
|
@ -325,7 +325,7 @@ static void MRU_SaveChanged ( LPWINEMRULIST mp )
|
||||||
witem->itemFlag &= ~WMRUIF_CHANGED;
|
witem->itemFlag &= ~WMRUIF_CHANGED;
|
||||||
realname[0] = 'a' + i;
|
realname[0] = 'a' + i;
|
||||||
err = RegSetValueExW(newkey, realname, 0,
|
err = RegSetValueExW(newkey, realname, 0,
|
||||||
(mp->extview.dwFlags & MRUF_BINARY_LIST) ?
|
(mp->extview.fFlags & MRU_BINARY) ?
|
||||||
REG_BINARY : REG_SZ,
|
REG_BINARY : REG_SZ,
|
||||||
&witem->datastart, witem->size);
|
&witem->datastart, witem->size);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -363,7 +363,7 @@ void WINAPI FreeMRUList (HANDLE hMRUList)
|
||||||
MRU_SaveChanged( mp );
|
MRU_SaveChanged( mp );
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<mp->extview.nMaxItems; i++)
|
for(i=0; i<mp->extview.uMax; i++)
|
||||||
Free(mp->array[i]);
|
Free(mp->array[i]);
|
||||||
|
|
||||||
Free(mp->realMRU);
|
Free(mp->realMRU);
|
||||||
|
@ -400,7 +400,7 @@ INT WINAPI FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData,
|
||||||
if (!mp || !mp->extview.u.string_cmpfn)
|
if (!mp || !mp->extview.u.string_cmpfn)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(!(mp->extview.dwFlags & MRUF_BINARY_LIST) && !mp->isUnicode) {
|
if(!(mp->extview.fFlags & MRU_BINARY) && !mp->isUnicode) {
|
||||||
DWORD len = WideCharToMultiByte(CP_ACP, 0, lpData, -1,
|
DWORD len = WideCharToMultiByte(CP_ACP, 0, lpData, -1,
|
||||||
NULL, 0, NULL, NULL);
|
NULL, 0, NULL, NULL);
|
||||||
dataA = Alloc(len);
|
dataA = Alloc(len);
|
||||||
|
@ -408,7 +408,7 @@ INT WINAPI FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData,
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; i<mp->cursize; i++) {
|
for(i=0; i<mp->cursize; i++) {
|
||||||
if (mp->extview.dwFlags & MRUF_BINARY_LIST) {
|
if (mp->extview.fFlags & MRU_BINARY) {
|
||||||
if (!mp->extview.u.binary_cmpfn(lpData, &mp->array[i]->datastart, cbData))
|
if (!mp->extview.u.binary_cmpfn(lpData, &mp->array[i]->datastart, cbData))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -480,7 +480,7 @@ INT WINAPI AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* either add a new entry or replace oldest */
|
/* either add a new entry or replace oldest */
|
||||||
if (mp->cursize < mp->extview.nMaxItems) {
|
if (mp->cursize < mp->extview.uMax) {
|
||||||
/* Add in a new item */
|
/* Add in a new item */
|
||||||
replace = mp->cursize;
|
replace = mp->cursize;
|
||||||
mp->cursize++;
|
mp->cursize++;
|
||||||
|
@ -509,7 +509,7 @@ INT WINAPI AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
|
||||||
TRACE("(%p, %p, %d) adding data, /%c/ now most current\n",
|
TRACE("(%p, %p, %d) adding data, /%c/ now most current\n",
|
||||||
hList, lpData, cbData, replace+'a');
|
hList, lpData, cbData, replace+'a');
|
||||||
|
|
||||||
if (!(mp->extview.dwFlags & MRUF_DELAYED_SAVE)) {
|
if (!(mp->extview.fFlags & MRU_CACHEWRITE)) {
|
||||||
/* save changed stuff right now */
|
/* save changed stuff right now */
|
||||||
MRU_SaveChanged( mp );
|
MRU_SaveChanged( mp );
|
||||||
}
|
}
|
||||||
|
@ -649,9 +649,9 @@ INT WINAPI FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* CreateMRUListLazy_common (internal)
|
* create_mru_list (internal)
|
||||||
*/
|
*/
|
||||||
static HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
static HANDLE create_mru_list(LPWINEMRULIST mp)
|
||||||
{
|
{
|
||||||
UINT i, err;
|
UINT i, err;
|
||||||
HKEY newkey;
|
HKEY newkey;
|
||||||
|
@ -663,12 +663,12 @@ static HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
||||||
/* get space to save indices that will turn into names
|
/* get space to save indices that will turn into names
|
||||||
* but in order of most to least recently used
|
* but in order of most to least recently used
|
||||||
*/
|
*/
|
||||||
mp->realMRU = Alloc((mp->extview.nMaxItems + 2) * sizeof(WCHAR));
|
mp->realMRU = Alloc((mp->extview.uMax + 2) * sizeof(WCHAR));
|
||||||
|
|
||||||
/* get space to save pointers to actual data in order of
|
/* get space to save pointers to actual data in order of
|
||||||
* 'a' to 'z' (0 to n).
|
* 'a' to 'z' (0 to n).
|
||||||
*/
|
*/
|
||||||
mp->array = Alloc(mp->extview.nMaxItems * sizeof(LPVOID));
|
mp->array = Alloc(mp->extview.uMax * sizeof(LPVOID));
|
||||||
|
|
||||||
/* open the sub key */
|
/* open the sub key */
|
||||||
if ((err = RegCreateKeyExW( mp->extview.hKey, mp->extview.lpszSubKey,
|
if ((err = RegCreateKeyExW( mp->extview.hKey, mp->extview.lpszSubKey,
|
||||||
|
@ -681,7 +681,7 @@ static HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
||||||
&dwdisp))) {
|
&dwdisp))) {
|
||||||
/* error - what to do ??? */
|
/* error - what to do ??? */
|
||||||
ERR("(%u %u %x %p %s %p): Could not open key, error=%d\n",
|
ERR("(%u %u %x %p %s %p): Could not open key, error=%d\n",
|
||||||
mp->extview.cbSize, mp->extview.nMaxItems, mp->extview.dwFlags,
|
mp->extview.cbSize, mp->extview.uMax, mp->extview.fFlags,
|
||||||
mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey),
|
mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey),
|
||||||
mp->extview.u.string_cmpfn, err);
|
mp->extview.u.string_cmpfn, err);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -689,7 +689,7 @@ static HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
||||||
|
|
||||||
/* get values from key 'MRUList' */
|
/* get values from key 'MRUList' */
|
||||||
if (newkey) {
|
if (newkey) {
|
||||||
datasize = (mp->extview.nMaxItems + 1) * sizeof(WCHAR);
|
datasize = (mp->extview.uMax + 1) * sizeof(WCHAR);
|
||||||
if((err=RegQueryValueExW( newkey, strMRUList, 0, &type,
|
if((err=RegQueryValueExW( newkey, strMRUList, 0, &type,
|
||||||
(LPBYTE)mp->realMRU, &datasize))) {
|
(LPBYTE)mp->realMRU, &datasize))) {
|
||||||
/* not present - set size to 1 (will become 0 later) */
|
/* not present - set size to 1 (will become 0 later) */
|
||||||
|
@ -726,7 +726,7 @@ static HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
||||||
mp->cursize = 0;
|
mp->cursize = 0;
|
||||||
|
|
||||||
TRACE("(%u %u %x %p %s %p): Current Size = %d\n",
|
TRACE("(%u %u %x %p %s %p): Current Size = %d\n",
|
||||||
mp->extview.cbSize, mp->extview.nMaxItems, mp->extview.dwFlags,
|
mp->extview.cbSize, mp->extview.uMax, mp->extview.fFlags,
|
||||||
mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey),
|
mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey),
|
||||||
mp->extview.u.string_cmpfn, mp->cursize);
|
mp->extview.u.string_cmpfn, mp->cursize);
|
||||||
return mp;
|
return mp;
|
||||||
|
@ -737,24 +737,22 @@ static HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
||||||
*
|
*
|
||||||
* See CreateMRUListLazyA.
|
* See CreateMRUListLazyA.
|
||||||
*/
|
*/
|
||||||
HANDLE WINAPI CreateMRUListLazyW (const CREATEMRULISTW *lpcml, DWORD dwParam2,
|
HANDLE WINAPI CreateMRUListLazyW (const MRUINFOW *infoW, DWORD dwParam2,
|
||||||
DWORD dwParam3, DWORD dwParam4)
|
DWORD dwParam3, DWORD dwParam4)
|
||||||
{
|
{
|
||||||
LPWINEMRULIST mp;
|
LPWINEMRULIST mp;
|
||||||
|
|
||||||
/* Native does not check for a NULL lpcml */
|
/* Native does not check for a NULL lpcml */
|
||||||
|
if (!infoW->hKey || IsBadStringPtrW(infoW->lpszSubKey, -1))
|
||||||
if (lpcml->cbSize != sizeof(CREATEMRULISTW) || !lpcml->hKey ||
|
|
||||||
IsBadStringPtrW(lpcml->lpszSubKey, -1))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mp = Alloc(sizeof(WINEMRULIST));
|
mp = Alloc(sizeof(WINEMRULIST));
|
||||||
memcpy(&mp->extview, lpcml, sizeof(CREATEMRULISTW));
|
memcpy(&mp->extview, infoW, sizeof(MRUINFOW));
|
||||||
mp->extview.lpszSubKey = Alloc((strlenW(lpcml->lpszSubKey) + 1) * sizeof(WCHAR));
|
mp->extview.lpszSubKey = Alloc((strlenW(infoW->lpszSubKey) + 1) * sizeof(WCHAR));
|
||||||
strcpyW(mp->extview.lpszSubKey, lpcml->lpszSubKey);
|
strcpyW(mp->extview.lpszSubKey, infoW->lpszSubKey);
|
||||||
mp->isUnicode = TRUE;
|
mp->isUnicode = TRUE;
|
||||||
|
|
||||||
return CreateMRUListLazy_common(mp);
|
return create_mru_list(mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -771,7 +769,7 @@ HANDLE WINAPI CreateMRUListLazyW (const CREATEMRULISTW *lpcml, DWORD dwParam2,
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Handle to MRU list.
|
* Handle to MRU list.
|
||||||
*/
|
*/
|
||||||
HANDLE WINAPI CreateMRUListLazyA (const CREATEMRULISTA *lpcml, DWORD dwParam2,
|
HANDLE WINAPI CreateMRUListLazyA (const MRUINFOA *lpcml, DWORD dwParam2,
|
||||||
DWORD dwParam3, DWORD dwParam4)
|
DWORD dwParam3, DWORD dwParam4)
|
||||||
{
|
{
|
||||||
LPWINEMRULIST mp;
|
LPWINEMRULIST mp;
|
||||||
|
@ -779,18 +777,18 @@ HANDLE WINAPI CreateMRUListLazyA (const CREATEMRULISTA *lpcml, DWORD dwParam2,
|
||||||
|
|
||||||
/* Native does not check for a NULL lpcml */
|
/* Native does not check for a NULL lpcml */
|
||||||
|
|
||||||
if (lpcml->cbSize != sizeof(CREATEMRULISTA) || !lpcml->hKey ||
|
if (lpcml->cbSize != sizeof(MRUINFOA) || !lpcml->hKey ||
|
||||||
IsBadStringPtrA(lpcml->lpszSubKey, -1))
|
IsBadStringPtrA(lpcml->lpszSubKey, -1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mp = Alloc(sizeof(WINEMRULIST));
|
mp = Alloc(sizeof(WINEMRULIST));
|
||||||
memcpy(&mp->extview, lpcml, sizeof(CREATEMRULISTW));
|
memcpy(&mp->extview, lpcml, sizeof(MRUINFOA));
|
||||||
len = MultiByteToWideChar(CP_ACP, 0, lpcml->lpszSubKey, -1, NULL, 0);
|
len = MultiByteToWideChar(CP_ACP, 0, lpcml->lpszSubKey, -1, NULL, 0);
|
||||||
mp->extview.lpszSubKey = Alloc(len * sizeof(WCHAR));
|
mp->extview.lpszSubKey = Alloc(len * sizeof(WCHAR));
|
||||||
MultiByteToWideChar(CP_ACP, 0, lpcml->lpszSubKey, -1,
|
MultiByteToWideChar(CP_ACP, 0, lpcml->lpszSubKey, -1,
|
||||||
mp->extview.lpszSubKey, len);
|
mp->extview.lpszSubKey, len);
|
||||||
mp->isUnicode = FALSE;
|
mp->isUnicode = FALSE;
|
||||||
return CreateMRUListLazy_common(mp);
|
return create_mru_list(mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -798,9 +796,9 @@ HANDLE WINAPI CreateMRUListLazyA (const CREATEMRULISTA *lpcml, DWORD dwParam2,
|
||||||
*
|
*
|
||||||
* See CreateMRUListA.
|
* See CreateMRUListA.
|
||||||
*/
|
*/
|
||||||
HANDLE WINAPI CreateMRUListW (const CREATEMRULISTW *lpcml)
|
HANDLE WINAPI CreateMRUListW (const MRUINFOW *infoW)
|
||||||
{
|
{
|
||||||
return CreateMRUListLazyW(lpcml, 0, 0, 0);
|
return CreateMRUListLazyW(infoW, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -814,7 +812,7 @@ HANDLE WINAPI CreateMRUListW (const CREATEMRULISTW *lpcml)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Handle to MRU list.
|
* Handle to MRU list.
|
||||||
*/
|
*/
|
||||||
HANDLE WINAPI CreateMRUListA (const CREATEMRULISTA *lpcml)
|
HANDLE WINAPI CreateMRUListA (const MRUINFOA *lpcml)
|
||||||
{
|
{
|
||||||
return CreateMRUListLazyA (lpcml, 0, 0, 0);
|
return CreateMRUListLazyA (lpcml, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -879,7 +877,7 @@ INT WINAPI EnumMRUListA (HANDLE hList, INT nItemPos, LPVOID lpBuffer,
|
||||||
desired -= 'a';
|
desired -= 'a';
|
||||||
TRACE("nItemPos=%d, desired=%d\n", nItemPos, desired);
|
TRACE("nItemPos=%d, desired=%d\n", nItemPos, desired);
|
||||||
witem = mp->array[desired];
|
witem = mp->array[desired];
|
||||||
if(mp->extview.dwFlags & MRUF_BINARY_LIST) {
|
if(mp->extview.fFlags & MRU_BINARY) {
|
||||||
datasize = min( witem->size, nBufferSize );
|
datasize = min( witem->size, nBufferSize );
|
||||||
memcpy( lpBuffer, &witem->datastart, datasize);
|
memcpy( lpBuffer, &witem->datastart, datasize);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -73,6 +73,8 @@ typedef struct
|
||||||
BOOL bCalDepressed; /* TRUE = cal button is depressed */
|
BOOL bCalDepressed; /* TRUE = cal button is depressed */
|
||||||
int bDropdownEnabled;
|
int bDropdownEnabled;
|
||||||
int select;
|
int select;
|
||||||
|
WCHAR charsEntered[4];
|
||||||
|
int nCharsEntered;
|
||||||
HFONT hFont;
|
HFONT hFont;
|
||||||
int nrFieldsAllocated;
|
int nrFieldsAllocated;
|
||||||
int nrFields;
|
int nrFields;
|
||||||
|
@ -165,7 +167,8 @@ DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *sy
|
||||||
if (flag == GDT_VALID) {
|
if (flag == GDT_VALID) {
|
||||||
if (systime->wYear < 1601 || systime->wYear > 30827 ||
|
if (systime->wYear < 1601 || systime->wYear > 30827 ||
|
||||||
systime->wMonth < 1 || systime->wMonth > 12 ||
|
systime->wMonth < 1 || systime->wMonth > 12 ||
|
||||||
systime->wDay < 1 || systime->wDay > 31 ||
|
systime->wDay < 1 ||
|
||||||
|
systime->wDay > MONTHCAL_MonthLength(systime->wMonth, systime->wYear) ||
|
||||||
systime->wHour > 23 ||
|
systime->wHour > 23 ||
|
||||||
systime->wMinute > 59 ||
|
systime->wMinute > 59 ||
|
||||||
systime->wSecond > 59 ||
|
systime->wSecond > 59 ||
|
||||||
|
@ -277,10 +280,11 @@ DATETIME_UseFormat (DATETIME_INFO *infoPtr, LPCWSTR formattxt)
|
||||||
|
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
DATETIME_SetFormatW (DATETIME_INFO *infoPtr, LPCWSTR lpszFormat)
|
DATETIME_SetFormatW (DATETIME_INFO *infoPtr, LPCWSTR format)
|
||||||
{
|
{
|
||||||
if (!lpszFormat) {
|
WCHAR format_buf[80];
|
||||||
WCHAR format_buf[80];
|
|
||||||
|
if (!format) {
|
||||||
DWORD format_item;
|
DWORD format_item;
|
||||||
|
|
||||||
if (infoPtr->dwStyle & DTS_LONGDATEFORMAT)
|
if (infoPtr->dwStyle & DTS_LONGDATEFORMAT)
|
||||||
|
@ -290,13 +294,13 @@ DATETIME_SetFormatW (DATETIME_INFO *infoPtr, LPCWSTR lpszFormat)
|
||||||
else /* DTS_SHORTDATEFORMAT */
|
else /* DTS_SHORTDATEFORMAT */
|
||||||
format_item = LOCALE_SSHORTDATE;
|
format_item = LOCALE_SSHORTDATE;
|
||||||
GetLocaleInfoW(LOCALE_USER_DEFAULT, format_item, format_buf, sizeof(format_buf)/sizeof(format_buf[0]));
|
GetLocaleInfoW(LOCALE_USER_DEFAULT, format_item, format_buf, sizeof(format_buf)/sizeof(format_buf[0]));
|
||||||
lpszFormat = format_buf;
|
format = format_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
DATETIME_UseFormat (infoPtr, lpszFormat);
|
DATETIME_UseFormat (infoPtr, format);
|
||||||
InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
|
InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
|
||||||
|
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -470,6 +474,9 @@ DATETIME_IncreaseField (DATETIME_INFO *infoPtr, int number, int delta)
|
||||||
case TWODIGITYEAR:
|
case TWODIGITYEAR:
|
||||||
case FULLYEAR:
|
case FULLYEAR:
|
||||||
date->wYear = wrap(date->wYear, delta, 1752, 9999);
|
date->wYear = wrap(date->wYear, delta, 1752, 9999);
|
||||||
|
if (date->wDay > MONTHCAL_MonthLength(date->wMonth, date->wYear))
|
||||||
|
/* This can happen when moving away from a leap year. */
|
||||||
|
date->wDay = MONTHCAL_MonthLength(date->wMonth, date->wYear);
|
||||||
MONTHCAL_CalculateDayOfWeek(date, TRUE);
|
MONTHCAL_CalculateDayOfWeek(date, TRUE);
|
||||||
break;
|
break;
|
||||||
case ONEDIGITMONTH:
|
case ONEDIGITMONTH:
|
||||||
|
@ -696,6 +703,13 @@ DATETIME_Refresh (DATETIME_INFO *infoPtr, HDC hdc)
|
||||||
/* fill if focused */
|
/* fill if focused */
|
||||||
HBRUSH hbr = CreateSolidBrush (comctl32_color.clrActiveCaption);
|
HBRUSH hbr = CreateSolidBrush (comctl32_color.clrActiveCaption);
|
||||||
|
|
||||||
|
if (infoPtr->nCharsEntered)
|
||||||
|
{
|
||||||
|
memcpy(txt, infoPtr->charsEntered, infoPtr->nCharsEntered * sizeof(WCHAR));
|
||||||
|
txt[infoPtr->nCharsEntered] = 0;
|
||||||
|
GetTextExtentPoint32W (hdc, txt, strlenW(txt), &size);
|
||||||
|
}
|
||||||
|
|
||||||
selection.left = 0;
|
selection.left = 0;
|
||||||
selection.top = 0;
|
selection.top = 0;
|
||||||
selection.right = size.cx;
|
selection.right = size.cx;
|
||||||
|
@ -755,6 +769,74 @@ static int DATETIME_GetPrevDateField(const DATETIME_INFO *infoPtr, int i)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DATETIME_ApplySelectedField (DATETIME_INFO *infoPtr)
|
||||||
|
{
|
||||||
|
int fieldNum = infoPtr->select & DTHT_DATEFIELD;
|
||||||
|
int i, val=0, clamp_day=0;
|
||||||
|
SYSTEMTIME date = infoPtr->date;
|
||||||
|
|
||||||
|
if (infoPtr->select == -1 || infoPtr->nCharsEntered == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i=0; i<infoPtr->nCharsEntered; i++)
|
||||||
|
val = val * 10 + infoPtr->charsEntered[i] - '0';
|
||||||
|
|
||||||
|
infoPtr->nCharsEntered = 0;
|
||||||
|
|
||||||
|
switch (infoPtr->fieldspec[fieldNum]) {
|
||||||
|
case ONEDIGITYEAR:
|
||||||
|
case TWODIGITYEAR:
|
||||||
|
date.wYear = date.wYear - (date.wYear%100) + val;
|
||||||
|
clamp_day = 1;
|
||||||
|
break;
|
||||||
|
case INVALIDFULLYEAR:
|
||||||
|
case FULLYEAR:
|
||||||
|
date.wYear = val;
|
||||||
|
clamp_day = 1;
|
||||||
|
break;
|
||||||
|
case ONEDIGITMONTH:
|
||||||
|
case TWODIGITMONTH:
|
||||||
|
date.wMonth = val;
|
||||||
|
clamp_day = 1;
|
||||||
|
break;
|
||||||
|
case ONEDIGITDAY:
|
||||||
|
case TWODIGITDAY:
|
||||||
|
date.wDay = val;
|
||||||
|
break;
|
||||||
|
case ONEDIGIT12HOUR:
|
||||||
|
case TWODIGIT12HOUR:
|
||||||
|
case ONEDIGIT24HOUR:
|
||||||
|
case TWODIGIT24HOUR:
|
||||||
|
/* FIXME: Preserve AM/PM for 12HOUR? */
|
||||||
|
date.wHour = val;
|
||||||
|
break;
|
||||||
|
case ONEDIGITMINUTE:
|
||||||
|
case TWODIGITMINUTE:
|
||||||
|
date.wMinute = val;
|
||||||
|
break;
|
||||||
|
case ONEDIGITSECOND:
|
||||||
|
case TWODIGITSECOND:
|
||||||
|
date.wSecond = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clamp_day && date.wDay > MONTHCAL_MonthLength(date.wMonth, date.wYear))
|
||||||
|
date.wDay = MONTHCAL_MonthLength(date.wMonth, date.wYear);
|
||||||
|
|
||||||
|
if (DATETIME_SetSystemTime(infoPtr, GDT_VALID, &date))
|
||||||
|
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DATETIME_SetSelectedField (DATETIME_INFO *infoPtr, int select)
|
||||||
|
{
|
||||||
|
DATETIME_ApplySelectedField(infoPtr);
|
||||||
|
|
||||||
|
infoPtr->select = select;
|
||||||
|
infoPtr->nCharsEntered = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static LRESULT
|
static LRESULT
|
||||||
DATETIME_LButtonDown (DATETIME_INFO *infoPtr, INT x, INT y)
|
DATETIME_LButtonDown (DATETIME_INFO *infoPtr, INT x, INT y)
|
||||||
{
|
{
|
||||||
|
@ -783,7 +865,8 @@ DATETIME_LButtonDown (DATETIME_INFO *infoPtr, INT x, INT y)
|
||||||
if (infoPtr->fieldspec[new] == FULLDAY) return 0;
|
if (infoPtr->fieldspec[new] == FULLDAY) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
infoPtr->select = new;
|
|
||||||
|
DATETIME_SetSelectedField(infoPtr, new);
|
||||||
|
|
||||||
if (infoPtr->select == DTHT_MCPOPUP) {
|
if (infoPtr->select == DTHT_MCPOPUP) {
|
||||||
RECT rcMonthCal;
|
RECT rcMonthCal;
|
||||||
|
@ -961,6 +1044,7 @@ DATETIME_KeyDown (DATETIME_INFO *infoPtr, DWORD vkCode)
|
||||||
{
|
{
|
||||||
int fieldNum = infoPtr->select & DTHT_DATEFIELD;
|
int fieldNum = infoPtr->select & DTHT_DATEFIELD;
|
||||||
int wrap = 0;
|
int wrap = 0;
|
||||||
|
int new;
|
||||||
|
|
||||||
if (!(infoPtr->haveFocus)) return 0;
|
if (!(infoPtr->haveFocus)) return 0;
|
||||||
if ((fieldNum==0) && (infoPtr->select)) return 0;
|
if ((fieldNum==0) && (infoPtr->select)) return 0;
|
||||||
|
@ -972,40 +1056,50 @@ DATETIME_KeyDown (DATETIME_INFO *infoPtr, DWORD vkCode)
|
||||||
switch (vkCode) {
|
switch (vkCode) {
|
||||||
case VK_ADD:
|
case VK_ADD:
|
||||||
case VK_UP:
|
case VK_UP:
|
||||||
|
infoPtr->nCharsEntered = 0;
|
||||||
DATETIME_IncreaseField (infoPtr, fieldNum, 1);
|
DATETIME_IncreaseField (infoPtr, fieldNum, 1);
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
||||||
break;
|
break;
|
||||||
case VK_SUBTRACT:
|
case VK_SUBTRACT:
|
||||||
case VK_DOWN:
|
case VK_DOWN:
|
||||||
|
infoPtr->nCharsEntered = 0;
|
||||||
DATETIME_IncreaseField (infoPtr, fieldNum, -1);
|
DATETIME_IncreaseField (infoPtr, fieldNum, -1);
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
||||||
break;
|
break;
|
||||||
case VK_HOME:
|
case VK_HOME:
|
||||||
|
infoPtr->nCharsEntered = 0;
|
||||||
DATETIME_IncreaseField (infoPtr, fieldNum, INT_MIN);
|
DATETIME_IncreaseField (infoPtr, fieldNum, INT_MIN);
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
||||||
break;
|
break;
|
||||||
case VK_END:
|
case VK_END:
|
||||||
|
infoPtr->nCharsEntered = 0;
|
||||||
DATETIME_IncreaseField (infoPtr, fieldNum, INT_MAX);
|
DATETIME_IncreaseField (infoPtr, fieldNum, INT_MAX);
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
||||||
break;
|
break;
|
||||||
case VK_LEFT:
|
case VK_LEFT:
|
||||||
|
new = infoPtr->select;
|
||||||
do {
|
do {
|
||||||
if (infoPtr->select == 0) {
|
if (new == 0) {
|
||||||
infoPtr->select = infoPtr->nrFields - 1;
|
new = new - 1;
|
||||||
wrap++;
|
wrap++;
|
||||||
} else {
|
} else {
|
||||||
infoPtr->select--;
|
new--;
|
||||||
}
|
}
|
||||||
} while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2));
|
} while ((infoPtr->fieldspec[new] & DT_STRING) && (wrap<2));
|
||||||
|
if (new != infoPtr->select)
|
||||||
|
DATETIME_SetSelectedField(infoPtr, new);
|
||||||
break;
|
break;
|
||||||
case VK_RIGHT:
|
case VK_RIGHT:
|
||||||
|
new = infoPtr->select;
|
||||||
do {
|
do {
|
||||||
infoPtr->select++;
|
new++;
|
||||||
if (infoPtr->select==infoPtr->nrFields) {
|
if (new==infoPtr->nrFields) {
|
||||||
infoPtr->select = 0;
|
new = 0;
|
||||||
wrap++;
|
wrap++;
|
||||||
}
|
}
|
||||||
} while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2));
|
} while ((infoPtr->fieldspec[new] & DT_STRING) && (wrap<2));
|
||||||
|
if (new != infoPtr->select)
|
||||||
|
DATETIME_SetSelectedField(infoPtr, new);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,80 +1115,20 @@ DATETIME_Char (DATETIME_INFO *infoPtr, WPARAM vkCode)
|
||||||
int fieldNum = infoPtr->select & DTHT_DATEFIELD;
|
int fieldNum = infoPtr->select & DTHT_DATEFIELD;
|
||||||
|
|
||||||
if (vkCode >= '0' && vkCode <= '9') {
|
if (vkCode >= '0' && vkCode <= '9') {
|
||||||
int num = vkCode-'0';
|
int maxChars;
|
||||||
int newDays;
|
int fieldSpec;
|
||||||
|
|
||||||
/* this is a somewhat simplified version of what Windows does */
|
infoPtr->charsEntered[infoPtr->nCharsEntered++] = vkCode;
|
||||||
SYSTEMTIME *date = &infoPtr->date;
|
|
||||||
switch (infoPtr->fieldspec[fieldNum]) {
|
fieldSpec = infoPtr->fieldspec[fieldNum];
|
||||||
case ONEDIGITYEAR:
|
|
||||||
case TWODIGITYEAR:
|
if (fieldSpec == INVALIDFULLYEAR || fieldSpec == FULLYEAR)
|
||||||
date->wYear = date->wYear - (date->wYear%100) +
|
maxChars = 4;
|
||||||
(date->wYear%10)*10 + num;
|
else
|
||||||
MONTHCAL_CalculateDayOfWeek(date, TRUE);
|
maxChars = 2;
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
|
||||||
break;
|
if (maxChars == infoPtr->nCharsEntered)
|
||||||
case INVALIDFULLYEAR:
|
DATETIME_ApplySelectedField(infoPtr);
|
||||||
case FULLYEAR:
|
|
||||||
/* reset current year initialy */
|
|
||||||
date->wYear = ((date->wYear/1000) ? 0 : 1)*(date->wYear%1000)*10 + num;
|
|
||||||
MONTHCAL_CalculateDayOfWeek(date, TRUE);
|
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
|
||||||
break;
|
|
||||||
case ONEDIGITMONTH:
|
|
||||||
case TWODIGITMONTH:
|
|
||||||
if ((date->wMonth%10) > 1 || num > 2)
|
|
||||||
date->wMonth = num;
|
|
||||||
else
|
|
||||||
date->wMonth = (date->wMonth%10)*10+num;
|
|
||||||
MONTHCAL_CalculateDayOfWeek(date, TRUE);
|
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
|
||||||
break;
|
|
||||||
case ONEDIGITDAY:
|
|
||||||
case TWODIGITDAY:
|
|
||||||
newDays = (date->wDay%10)*10+num;
|
|
||||||
if (newDays > MONTHCAL_MonthLength(date->wMonth, date->wYear))
|
|
||||||
date->wDay = num;
|
|
||||||
else
|
|
||||||
date->wDay = newDays;
|
|
||||||
MONTHCAL_CalculateDayOfWeek(date, TRUE);
|
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
|
||||||
break;
|
|
||||||
case ONEDIGIT12HOUR:
|
|
||||||
case TWODIGIT12HOUR:
|
|
||||||
if ((date->wHour%10) > 1 || num > 2)
|
|
||||||
date->wHour = num;
|
|
||||||
else
|
|
||||||
date->wHour = (date->wHour%10)*10+num;
|
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
|
||||||
break;
|
|
||||||
case ONEDIGIT24HOUR:
|
|
||||||
case TWODIGIT24HOUR:
|
|
||||||
if ((date->wHour%10) > 2)
|
|
||||||
date->wHour = num;
|
|
||||||
else if ((date->wHour%10) == 2 && num > 3)
|
|
||||||
date->wHour = num;
|
|
||||||
else
|
|
||||||
date->wHour = (date->wHour%10)*10+num;
|
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
|
||||||
break;
|
|
||||||
case ONEDIGITMINUTE:
|
|
||||||
case TWODIGITMINUTE:
|
|
||||||
if ((date->wMinute%10) > 5)
|
|
||||||
date->wMinute = num;
|
|
||||||
else
|
|
||||||
date->wMinute = (date->wMinute%10)*10+num;
|
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
|
||||||
break;
|
|
||||||
case ONEDIGITSECOND:
|
|
||||||
case TWODIGITSECOND:
|
|
||||||
if ((date->wSecond%10) > 5)
|
|
||||||
date->wSecond = num;
|
|
||||||
else
|
|
||||||
date->wSecond = (date->wSecond%10)*10+num;
|
|
||||||
DATETIME_SendDateTimeChangeNotify (infoPtr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1132,6 +1166,7 @@ DATETIME_KillFocus (DATETIME_INFO *infoPtr, HWND lostFocus)
|
||||||
if (infoPtr->haveFocus) {
|
if (infoPtr->haveFocus) {
|
||||||
DATETIME_SendSimpleNotify (infoPtr, NM_KILLFOCUS);
|
DATETIME_SendSimpleNotify (infoPtr, NM_KILLFOCUS);
|
||||||
infoPtr->haveFocus = 0;
|
infoPtr->haveFocus = 0;
|
||||||
|
DATETIME_SetSelectedField (infoPtr, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
|
InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
|
||||||
|
|
|
@ -384,15 +384,16 @@ static void IPADDRESS_SetFocusToField (const IPADDRESS_INFO *infoPtr, INT index)
|
||||||
|
|
||||||
static BOOL IPADDRESS_ConstrainField (const IPADDRESS_INFO *infoPtr, int currentfield)
|
static BOOL IPADDRESS_ConstrainField (const IPADDRESS_INFO *infoPtr, int currentfield)
|
||||||
{
|
{
|
||||||
const IPPART_INFO *part = &infoPtr->Part[currentfield];
|
|
||||||
WCHAR field[10];
|
|
||||||
static const WCHAR fmt[] = { '%', 'd', 0 };
|
static const WCHAR fmt[] = { '%', 'd', 0 };
|
||||||
|
const IPPART_INFO *part;
|
||||||
int curValue, newValue;
|
int curValue, newValue;
|
||||||
|
WCHAR field[10];
|
||||||
|
|
||||||
TRACE("(currentfield=%d)\n", currentfield);
|
TRACE("(currentfield=%d)\n", currentfield);
|
||||||
|
|
||||||
if (currentfield < 0 || currentfield > 3) return FALSE;
|
if (currentfield < 0 || currentfield > 3) return FALSE;
|
||||||
|
|
||||||
|
part = &infoPtr->Part[currentfield];
|
||||||
if (!GetWindowTextW (part->EditHwnd, field, 4)) return FALSE;
|
if (!GetWindowTextW (part->EditHwnd, field, 4)) return FALSE;
|
||||||
|
|
||||||
curValue = atoiW(field);
|
curValue = atoiW(field);
|
||||||
|
|
|
@ -315,7 +315,6 @@ typedef struct tagLISTVIEW_INFO
|
||||||
COLORREF clrBk;
|
COLORREF clrBk;
|
||||||
COLORREF clrText;
|
COLORREF clrText;
|
||||||
COLORREF clrTextBk;
|
COLORREF clrTextBk;
|
||||||
BOOL bDefaultBkColor;
|
|
||||||
|
|
||||||
/* font */
|
/* font */
|
||||||
HFONT hDefaultFont;
|
HFONT hDefaultFont;
|
||||||
|
@ -1498,6 +1497,70 @@ static BOOL iterator_visibleitems(ITERATOR *i, const LISTVIEW_INFO *infoPtr, HDC
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove common elements from two iterators */
|
||||||
|
/* Passed iterators have to point on the first elements */
|
||||||
|
static BOOL iterator_remove_common_items(ITERATOR *iter1, ITERATOR *iter2)
|
||||||
|
{
|
||||||
|
if(!iter1->ranges || !iter2->ranges) {
|
||||||
|
int lower, upper;
|
||||||
|
|
||||||
|
if(iter1->ranges || iter2->ranges ||
|
||||||
|
(iter1->range.lower<iter2->range.lower && iter1->range.upper>iter2->range.upper) ||
|
||||||
|
(iter1->range.lower>iter2->range.lower && iter1->range.upper<iter2->range.upper)) {
|
||||||
|
ERR("result is not a one range iterator\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iter1->range.lower==-1 || iter2->range.lower==-1)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
lower = iter1->range.lower;
|
||||||
|
upper = iter1->range.upper;
|
||||||
|
|
||||||
|
if(lower < iter2->range.lower)
|
||||||
|
iter1->range.upper = iter2->range.lower;
|
||||||
|
else if(upper > iter2->range.upper)
|
||||||
|
iter1->range.lower = iter2->range.upper;
|
||||||
|
else
|
||||||
|
iter1->range.lower = iter1->range.upper = -1;
|
||||||
|
|
||||||
|
if(iter2->range.lower < lower)
|
||||||
|
iter2->range.upper = lower;
|
||||||
|
else if(iter2->range.upper > upper)
|
||||||
|
iter2->range.lower = upper;
|
||||||
|
else
|
||||||
|
iter2->range.lower = iter2->range.upper = -1;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator_next(iter1);
|
||||||
|
iterator_next(iter2);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
if(iter1->nItem==-1 || iter2->nItem==-1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(iter1->nItem == iter2->nItem) {
|
||||||
|
int delete = iter1->nItem;
|
||||||
|
|
||||||
|
iterator_prev(iter1);
|
||||||
|
iterator_prev(iter2);
|
||||||
|
ranges_delitem(iter1->ranges, delete);
|
||||||
|
ranges_delitem(iter2->ranges, delete);
|
||||||
|
iterator_next(iter1);
|
||||||
|
iterator_next(iter2);
|
||||||
|
} else if(iter1->nItem > iter2->nItem)
|
||||||
|
iterator_next(iter2);
|
||||||
|
else
|
||||||
|
iterator_next(iter1);
|
||||||
|
}
|
||||||
|
|
||||||
|
iter1->nItem = iter1->range.lower = iter1->range.upper = -1;
|
||||||
|
iter2->nItem = iter2->range.lower = iter2->range.upper = -1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/******** Misc helper functions ************************************/
|
/******** Misc helper functions ************************************/
|
||||||
|
|
||||||
static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
|
static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
|
||||||
|
@ -1636,19 +1699,8 @@ static inline BOOL LISTVIEW_GetItemW(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpL
|
||||||
/* used to handle collapse main item column case */
|
/* used to handle collapse main item column case */
|
||||||
static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc)
|
static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc)
|
||||||
{
|
{
|
||||||
BOOL Ret = FALSE;
|
return (infoPtr->rcFocus.left < infoPtr->rcFocus.right) ?
|
||||||
|
DrawFocusRect(hdc, &infoPtr->rcFocus) : FALSE;
|
||||||
if (infoPtr->rcFocus.left < infoPtr->rcFocus.right)
|
|
||||||
{
|
|
||||||
DWORD dwOldBkColor, dwOldTextColor;
|
|
||||||
|
|
||||||
dwOldBkColor = SetBkColor(hdc, RGB(255, 255, 255));
|
|
||||||
dwOldTextColor = SetBkColor(hdc, RGB(0, 0, 0));
|
|
||||||
Ret = DrawFocusRect(hdc, &infoPtr->rcFocus);
|
|
||||||
SetBkColor(hdc, dwOldBkColor);
|
|
||||||
SetBkColor(hdc, dwOldTextColor);
|
|
||||||
}
|
|
||||||
return Ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Listview invalidation functions: use _only_ these functions to invalidate */
|
/* Listview invalidation functions: use _only_ these functions to invalidate */
|
||||||
|
@ -3745,7 +3797,7 @@ static void LISTVIEW_MarqueeHighlight(LISTVIEW_INFO *infoPtr, const POINT *coord
|
||||||
{
|
{
|
||||||
BOOL controlDown = FALSE;
|
BOOL controlDown = FALSE;
|
||||||
LVITEMW item;
|
LVITEMW item;
|
||||||
ITERATOR i;
|
ITERATOR old_elems, new_elems;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
|
||||||
if (coords_offs->x > infoPtr->marqueeOrigin.x)
|
if (coords_offs->x > infoPtr->marqueeOrigin.x)
|
||||||
|
@ -3788,54 +3840,55 @@ static void LISTVIEW_MarqueeHighlight(LISTVIEW_INFO *infoPtr, const POINT *coord
|
||||||
if ((scroll & SCROLL_DOWN) && (coords_orig->y >= infoPtr->rcList.bottom))
|
if ((scroll & SCROLL_DOWN) && (coords_orig->y >= infoPtr->rcList.bottom))
|
||||||
LISTVIEW_Scroll(infoPtr, 0, (coords_orig->y - infoPtr->rcList.bottom));
|
LISTVIEW_Scroll(infoPtr, 0, (coords_orig->y - infoPtr->rcList.bottom));
|
||||||
|
|
||||||
/* Invert the items in the old marquee rectangle */
|
iterator_frameditems_absolute(&old_elems, infoPtr, &infoPtr->marqueeRect);
|
||||||
iterator_frameditems_absolute(&i, infoPtr, &infoPtr->marqueeRect);
|
|
||||||
|
|
||||||
while (iterator_next(&i))
|
|
||||||
{
|
|
||||||
if (i.nItem > -1)
|
|
||||||
{
|
|
||||||
if (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED) == LVIS_SELECTED)
|
|
||||||
item.state = 0;
|
|
||||||
else
|
|
||||||
item.state = LVIS_SELECTED;
|
|
||||||
|
|
||||||
item.stateMask = LVIS_SELECTED;
|
|
||||||
|
|
||||||
LISTVIEW_SetItemState(infoPtr, i.nItem, &item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator_destroy(&i);
|
|
||||||
|
|
||||||
CopyRect(&infoPtr->marqueeRect, &rect);
|
CopyRect(&infoPtr->marqueeRect, &rect);
|
||||||
|
|
||||||
CopyRect(&infoPtr->marqueeDrawRect, &rect);
|
CopyRect(&infoPtr->marqueeDrawRect, &rect);
|
||||||
OffsetRect(&infoPtr->marqueeDrawRect, offset->x, offset->y);
|
OffsetRect(&infoPtr->marqueeDrawRect, offset->x, offset->y);
|
||||||
|
|
||||||
/* Iterate over the items within our marquee rectangle */
|
iterator_frameditems_absolute(&new_elems, infoPtr, &infoPtr->marqueeRect);
|
||||||
iterator_frameditems_absolute(&i, infoPtr, &infoPtr->marqueeRect);
|
iterator_remove_common_items(&old_elems, &new_elems);
|
||||||
|
|
||||||
if (GetKeyState(VK_CONTROL) & 0x8000)
|
/* Iterate over no longer selected items */
|
||||||
controlDown = TRUE;
|
while (iterator_next(&old_elems))
|
||||||
|
|
||||||
while (iterator_next(&i))
|
|
||||||
{
|
{
|
||||||
if (i.nItem > -1)
|
if (old_elems.nItem > -1)
|
||||||
{
|
{
|
||||||
/* If CTRL is pressed, invert. If not, always select the item. */
|
if (LISTVIEW_GetItemState(infoPtr, old_elems.nItem, LVIS_SELECTED) == LVIS_SELECTED)
|
||||||
if ((controlDown) && (LISTVIEW_GetItemState(infoPtr, i.nItem, LVIS_SELECTED)))
|
|
||||||
item.state = 0;
|
item.state = 0;
|
||||||
else
|
else
|
||||||
item.state = LVIS_SELECTED;
|
item.state = LVIS_SELECTED;
|
||||||
|
|
||||||
item.stateMask = LVIS_SELECTED;
|
item.stateMask = LVIS_SELECTED;
|
||||||
|
|
||||||
LISTVIEW_SetItemState(infoPtr, i.nItem, &item);
|
LISTVIEW_SetItemState(infoPtr, old_elems.nItem, &item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iterator_destroy(&old_elems);
|
||||||
|
|
||||||
|
|
||||||
|
/* Iterate over newly selected items */
|
||||||
|
if (GetKeyState(VK_CONTROL) & 0x8000)
|
||||||
|
controlDown = TRUE;
|
||||||
|
|
||||||
|
while (iterator_next(&new_elems))
|
||||||
|
{
|
||||||
|
if (new_elems.nItem > -1)
|
||||||
|
{
|
||||||
|
/* If CTRL is pressed, invert. If not, always select the item. */
|
||||||
|
if ((controlDown) && (LISTVIEW_GetItemState(infoPtr, new_elems.nItem, LVIS_SELECTED)))
|
||||||
|
item.state = 0;
|
||||||
|
else
|
||||||
|
item.state = LVIS_SELECTED;
|
||||||
|
|
||||||
|
item.stateMask = LVIS_SELECTED;
|
||||||
|
|
||||||
|
LISTVIEW_SetItemState(infoPtr, new_elems.nItem, &item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterator_destroy(&new_elems);
|
||||||
|
|
||||||
iterator_destroy(&i);
|
|
||||||
LISTVIEW_InvalidateRect(infoPtr, &rect);
|
LISTVIEW_InvalidateRect(infoPtr, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4284,9 +4337,9 @@ static BOOL set_sub_item(const LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem,
|
||||||
particularly useful. We currently do not actually do anything with
|
particularly useful. We currently do not actually do anything with
|
||||||
the flag on subitems.
|
the flag on subitems.
|
||||||
*/
|
*/
|
||||||
if (lpLVItem->mask & ~(LVIF_TEXT | LVIF_IMAGE | LVIF_STATE)) return FALSE;
|
if (lpLVItem->mask & ~(LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_DI_SETITEM)) return FALSE;
|
||||||
if (!(lpLVItem->mask & (LVIF_TEXT | LVIF_IMAGE | LVIF_STATE))) return TRUE;
|
if (!(lpLVItem->mask & (LVIF_TEXT | LVIF_IMAGE | LVIF_STATE))) return TRUE;
|
||||||
|
|
||||||
/* get the subitem structure, and create it if not there */
|
/* get the subitem structure, and create it if not there */
|
||||||
hdpaSubItems = DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
|
hdpaSubItems = DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
|
||||||
assert (hdpaSubItems);
|
assert (hdpaSubItems);
|
||||||
|
@ -4354,6 +4407,9 @@ static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *infoPtr, LVITEMW *lpLVItem, BOOL is
|
||||||
if (!lpLVItem || lpLVItem->iItem < 0 || lpLVItem->iItem >= infoPtr->nItemCount)
|
if (!lpLVItem || lpLVItem->iItem < 0 || lpLVItem->iItem >= infoPtr->nItemCount)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* Invalidate old item area */
|
||||||
|
LISTVIEW_InvalidateItem(infoPtr, lpLVItem->iItem);
|
||||||
|
|
||||||
/* For efficiency, we transform the lpLVItem->pszText to Unicode here */
|
/* For efficiency, we transform the lpLVItem->pszText to Unicode here */
|
||||||
if ((lpLVItem->mask & LVIF_TEXT) && is_text(lpLVItem->pszText))
|
if ((lpLVItem->mask & LVIF_TEXT) && is_text(lpLVItem->pszText))
|
||||||
{
|
{
|
||||||
|
@ -4973,6 +5029,9 @@ static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc, const RECT *prcEra
|
||||||
|
|
||||||
SelectObject(hdc, hbmp);
|
SelectObject(hdc, hbmp);
|
||||||
SelectObject(hdc, infoPtr->hFont);
|
SelectObject(hdc, infoPtr->hFont);
|
||||||
|
|
||||||
|
if(GetClipBox(hdcOrig, &rcClient))
|
||||||
|
IntersectClipRect(hdc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
|
||||||
} else {
|
} else {
|
||||||
/* Save dc values we're gonna trash while drawing
|
/* Save dc values we're gonna trash while drawing
|
||||||
* FIXME: Should be done in LISTVIEW_DrawItem() */
|
* FIXME: Should be done in LISTVIEW_DrawItem() */
|
||||||
|
@ -5054,11 +5113,7 @@ enddraw:
|
||||||
|
|
||||||
/* Draw marquee rectangle if appropriate */
|
/* Draw marquee rectangle if appropriate */
|
||||||
if (infoPtr->bMarqueeSelect)
|
if (infoPtr->bMarqueeSelect)
|
||||||
{
|
|
||||||
SetBkColor(hdc, RGB(255, 255, 255));
|
|
||||||
SetTextColor(hdc, RGB(0, 0, 0));
|
|
||||||
DrawFocusRect(hdc, &infoPtr->marqueeDrawRect);
|
DrawFocusRect(hdc, &infoPtr->marqueeDrawRect);
|
||||||
}
|
|
||||||
|
|
||||||
if (cdmode & CDRF_NOTIFYPOSTPAINT)
|
if (cdmode & CDRF_NOTIFYPOSTPAINT)
|
||||||
notify_postpaint(infoPtr, &nmlvcd);
|
notify_postpaint(infoPtr, &nmlvcd);
|
||||||
|
@ -5678,7 +5733,7 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
|
||||||
WCHAR szDispText[DISP_TEXT_SIZE] = { 0 };
|
WCHAR szDispText[DISP_TEXT_SIZE] = { 0 };
|
||||||
NMLVDISPINFOW dispInfo;
|
NMLVDISPINFOW dispInfo;
|
||||||
INT editedItem = infoPtr->nEditLabelItem;
|
INT editedItem = infoPtr->nEditLabelItem;
|
||||||
BOOL bSame;
|
BOOL same;
|
||||||
WCHAR *pszText = NULL;
|
WCHAR *pszText = NULL;
|
||||||
BOOL res;
|
BOOL res;
|
||||||
|
|
||||||
|
@ -5698,9 +5753,6 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
|
||||||
|
|
||||||
TRACE("(pszText=%s, isW=%d)\n", debugtext_t(pszText, isW), isW);
|
TRACE("(pszText=%s, isW=%d)\n", debugtext_t(pszText, isW), isW);
|
||||||
|
|
||||||
infoPtr->nEditLabelItem = -1;
|
|
||||||
infoPtr->hwndEdit = 0;
|
|
||||||
|
|
||||||
ZeroMemory(&dispInfo, sizeof(dispInfo));
|
ZeroMemory(&dispInfo, sizeof(dispInfo));
|
||||||
dispInfo.item.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
|
dispInfo.item.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
|
||||||
dispInfo.item.iItem = editedItem;
|
dispInfo.item.iItem = editedItem;
|
||||||
|
@ -5715,32 +5767,34 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isW)
|
if (isW)
|
||||||
bSame = (lstrcmpW(dispInfo.item.pszText, pszText) == 0);
|
same = (lstrcmpW(dispInfo.item.pszText, pszText) == 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LPWSTR tmp = textdupTtoW(pszText, FALSE);
|
LPWSTR tmp = textdupTtoW(pszText, FALSE);
|
||||||
bSame = (lstrcmpW(dispInfo.item.pszText, tmp) == 0);
|
same = (lstrcmpW(dispInfo.item.pszText, tmp) == 0);
|
||||||
textfreeT(tmp, FALSE);
|
textfreeT(tmp, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the text from the edit in */
|
/* add the text from the edit in */
|
||||||
dispInfo.item.mask |= LVIF_TEXT;
|
dispInfo.item.mask |= LVIF_TEXT;
|
||||||
dispInfo.item.pszText = bSame ? NULL : pszText;
|
dispInfo.item.pszText = same ? NULL : pszText;
|
||||||
dispInfo.item.cchTextMax = bSame ? 0 : textlenT(pszText, isW);
|
dispInfo.item.cchTextMax = textlenT(dispInfo.item.pszText, isW);
|
||||||
|
|
||||||
/* Do we need to update the Item Text */
|
/* Do we need to update the Item Text */
|
||||||
if (!notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW))
|
res = notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW);
|
||||||
{
|
|
||||||
res = FALSE;
|
infoPtr->nEditLabelItem = -1;
|
||||||
goto cleanup;
|
infoPtr->hwndEdit = 0;
|
||||||
}
|
|
||||||
|
if (!res) goto cleanup;
|
||||||
|
|
||||||
if (!IsWindow(hwndSelf))
|
if (!IsWindow(hwndSelf))
|
||||||
{
|
{
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (!pszText) return TRUE;
|
if (!pszText) return TRUE;
|
||||||
if (bSame)
|
if (same)
|
||||||
{
|
{
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -7823,10 +7877,8 @@ static BOOL LISTVIEW_RedrawItems(const LISTVIEW_INFO *infoPtr, INT nFirst, INT n
|
||||||
* is passed, then the scroll will be 0. (per MSDN 7/2002)
|
* is passed, then the scroll will be 0. (per MSDN 7/2002)
|
||||||
*
|
*
|
||||||
* For: (per experimentation with native control and CSpy ListView)
|
* For: (per experimentation with native control and CSpy ListView)
|
||||||
* LV_VIEW_ICON dy=1 = 1 pixel (vertical only)
|
* LV_VIEW_ICON scrolling in any direction is allowed
|
||||||
* dx ignored
|
* LV_VIEW_SMALLICON scrolling in any direction is allowed
|
||||||
* LV_VIEW_SMALLICON dy=1 = 1 pixel (vertical only)
|
|
||||||
* dx ignored
|
|
||||||
* LV_VIEW_LIST dx=1 = 1 column (horizontal only)
|
* LV_VIEW_LIST dx=1 = 1 column (horizontal only)
|
||||||
* but will only scroll 1 column per message
|
* but will only scroll 1 column per message
|
||||||
* no matter what the value.
|
* no matter what the value.
|
||||||
|
@ -7846,7 +7898,6 @@ static BOOL LISTVIEW_Scroll(LISTVIEW_INFO *infoPtr, INT dx, INT dy)
|
||||||
if (dy != 0) return FALSE;
|
if (dy != 0) return FALSE;
|
||||||
break;
|
break;
|
||||||
default: /* icon */
|
default: /* icon */
|
||||||
dx = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7872,7 +7923,6 @@ static BOOL LISTVIEW_SetBkColor(LISTVIEW_INFO *infoPtr, COLORREF clrBk)
|
||||||
{
|
{
|
||||||
TRACE("(clrBk=%x)\n", clrBk);
|
TRACE("(clrBk=%x)\n", clrBk);
|
||||||
|
|
||||||
infoPtr->bDefaultBkColor = FALSE;
|
|
||||||
if(infoPtr->clrBk != clrBk) {
|
if(infoPtr->clrBk != clrBk) {
|
||||||
if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);
|
if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);
|
||||||
infoPtr->clrBk = clrBk;
|
infoPtr->clrBk = clrBk;
|
||||||
|
@ -8803,8 +8853,8 @@ static BOOL LISTVIEW_SetItemTextT(LISTVIEW_INFO *infoPtr, INT nItem, const LVITE
|
||||||
{
|
{
|
||||||
LVITEMW lvItem;
|
LVITEMW lvItem;
|
||||||
|
|
||||||
if (nItem < 0 && nItem >= infoPtr->nItemCount) return FALSE;
|
if (!lpLVItem || nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE;
|
||||||
|
|
||||||
lvItem.iItem = nItem;
|
lvItem.iItem = nItem;
|
||||||
lvItem.iSubItem = lpLVItem->iSubItem;
|
lvItem.iSubItem = lpLVItem->iSubItem;
|
||||||
lvItem.mask = LVIF_TEXT;
|
lvItem.mask = LVIF_TEXT;
|
||||||
|
@ -9116,9 +9166,7 @@ static BOOL LISTVIEW_SortItems(LISTVIEW_INFO *infoPtr, PFNLVCOMPARE pfnCompare,
|
||||||
/* I believe nHotItem should be left alone, see LISTVIEW_ShiftIndices */
|
/* I believe nHotItem should be left alone, see LISTVIEW_ShiftIndices */
|
||||||
|
|
||||||
/* refresh the display */
|
/* refresh the display */
|
||||||
if (infoPtr->uView != LV_VIEW_ICON && infoPtr->uView != LV_VIEW_SMALLICON)
|
LISTVIEW_InvalidateList(infoPtr);
|
||||||
LISTVIEW_InvalidateList(infoPtr);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9265,7 +9313,6 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs)
|
||||||
infoPtr->clrText = CLR_DEFAULT;
|
infoPtr->clrText = CLR_DEFAULT;
|
||||||
infoPtr->clrTextBk = CLR_DEFAULT;
|
infoPtr->clrTextBk = CLR_DEFAULT;
|
||||||
LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
|
LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
|
||||||
infoPtr->bDefaultBkColor = TRUE;
|
|
||||||
|
|
||||||
/* set default values */
|
/* set default values */
|
||||||
infoPtr->nFocusedItem = -1;
|
infoPtr->nFocusedItem = -1;
|
||||||
|
@ -9595,6 +9642,7 @@ static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode,
|
||||||
{
|
{
|
||||||
INT nOldScrollPos, nNewScrollPos;
|
INT nOldScrollPos, nNewScrollPos;
|
||||||
SCROLLINFO scrollInfo;
|
SCROLLINFO scrollInfo;
|
||||||
|
BOOL is_an_icon;
|
||||||
|
|
||||||
TRACE("(nScrollCode=%d(%s), nScrollDiff=%d)\n", nScrollCode,
|
TRACE("(nScrollCode=%d(%s), nScrollDiff=%d)\n", nScrollCode,
|
||||||
debugscrollcode(nScrollCode), nScrollDiff);
|
debugscrollcode(nScrollCode), nScrollDiff);
|
||||||
|
@ -9604,6 +9652,8 @@ static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode,
|
||||||
scrollInfo.cbSize = sizeof(SCROLLINFO);
|
scrollInfo.cbSize = sizeof(SCROLLINFO);
|
||||||
scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
|
scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS;
|
||||||
|
|
||||||
|
is_an_icon = ((infoPtr->uView == LV_VIEW_ICON) || (infoPtr->uView == LV_VIEW_SMALLICON));
|
||||||
|
|
||||||
if (!GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)) return 1;
|
if (!GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)) return 1;
|
||||||
|
|
||||||
nOldScrollPos = scrollInfo.nPos;
|
nOldScrollPos = scrollInfo.nPos;
|
||||||
|
@ -9614,11 +9664,11 @@ static LRESULT LISTVIEW_HScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SB_LINELEFT:
|
case SB_LINELEFT:
|
||||||
nScrollDiff = -1;
|
nScrollDiff = (is_an_icon) ? -LISTVIEW_SCROLL_ICON_LINE_SIZE : -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SB_LINERIGHT:
|
case SB_LINERIGHT:
|
||||||
nScrollDiff = 1;
|
nScrollDiff = (is_an_icon) ? LISTVIEW_SCROLL_ICON_LINE_SIZE : 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SB_PAGELEFT:
|
case SB_PAGELEFT:
|
||||||
|
@ -10160,7 +10210,6 @@ static LRESULT LISTVIEW_NCDestroy(LISTVIEW_INFO *infoPtr)
|
||||||
*/
|
*/
|
||||||
static LRESULT LISTVIEW_Notify(LISTVIEW_INFO *infoPtr, const NMHDR *lpnmhdr)
|
static LRESULT LISTVIEW_Notify(LISTVIEW_INFO *infoPtr, const NMHDR *lpnmhdr)
|
||||||
{
|
{
|
||||||
HWND hwndSelf = infoPtr->hwndSelf;
|
|
||||||
const NMHEADERW *lpnmh;
|
const NMHEADERW *lpnmh;
|
||||||
|
|
||||||
TRACE("(lpnmhdr=%p)\n", lpnmhdr);
|
TRACE("(lpnmhdr=%p)\n", lpnmhdr);
|
||||||
|
@ -10213,10 +10262,6 @@ static LRESULT LISTVIEW_Notify(LISTVIEW_INFO *infoPtr, const NMHDR *lpnmhdr)
|
||||||
LISTVIEW_InvalidateList(infoPtr);
|
LISTVIEW_InvalidateList(infoPtr);
|
||||||
notify_forward_header(infoPtr, lpnmh);
|
notify_forward_header(infoPtr, lpnmh);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
case HDN_ITEMCHANGINGW:
|
|
||||||
case HDN_ITEMCHANGINGA:
|
|
||||||
return notify_forward_header(infoPtr, lpnmh);
|
|
||||||
|
|
||||||
case HDN_ITEMCHANGEDW:
|
case HDN_ITEMCHANGEDW:
|
||||||
case HDN_ITEMCHANGEDA:
|
case HDN_ITEMCHANGEDA:
|
||||||
|
@ -10224,10 +10269,6 @@ static LRESULT LISTVIEW_Notify(LISTVIEW_INFO *infoPtr, const NMHDR *lpnmhdr)
|
||||||
COLUMN_INFO *lpColumnInfo;
|
COLUMN_INFO *lpColumnInfo;
|
||||||
HDITEMW hdi;
|
HDITEMW hdi;
|
||||||
INT dx, cxy;
|
INT dx, cxy;
|
||||||
|
|
||||||
notify_forward_header(infoPtr, lpnmh);
|
|
||||||
if (!IsWindow(hwndSelf))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!lpnmh->pitem || !(lpnmh->pitem->mask & HDI_WIDTH))
|
if (!lpnmh->pitem || !(lpnmh->pitem->mask & HDI_WIDTH))
|
||||||
{
|
{
|
||||||
|
@ -11528,11 +11569,6 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
case WM_SYSCOLORCHANGE:
|
case WM_SYSCOLORCHANGE:
|
||||||
COMCTL32_RefreshSysColors();
|
COMCTL32_RefreshSysColors();
|
||||||
if (infoPtr->bDefaultBkColor)
|
|
||||||
{
|
|
||||||
LISTVIEW_SetBkColor(infoPtr, comctl32_color.clrWindow);
|
|
||||||
infoPtr->bDefaultBkColor = TRUE;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* case WM_TIMER: */
|
/* case WM_TIMER: */
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Copyright 1999 Chris Morgan <cmorgan@wpi.edu> and
|
* Copyright 1999 Chris Morgan <cmorgan@wpi.edu> and
|
||||||
* James Abbatiello <abbeyj@wpi.edu>
|
* James Abbatiello <abbeyj@wpi.edu>
|
||||||
* Copyright 2000 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
|
* Copyright 2000 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
|
||||||
* Copyright 2009, 2010 Nikolay Sivov
|
* Copyright 2009-2011 Nikolay Sivov
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -33,7 +33,6 @@
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* -- MCM_[GS]ETUNICODEFORMAT
|
* -- MCM_[GS]ETUNICODEFORMAT
|
||||||
* -- MONTHCAL_GetMonthRange
|
|
||||||
* -- handle resources better (doesn't work now);
|
* -- handle resources better (doesn't work now);
|
||||||
* -- take care of internationalization.
|
* -- take care of internationalization.
|
||||||
* -- keyboard handling.
|
* -- keyboard handling.
|
||||||
|
@ -77,6 +76,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(monthcal);
|
||||||
/* convert from days to 100 nanoseconds unit - used as FILETIME unit */
|
/* convert from days to 100 nanoseconds unit - used as FILETIME unit */
|
||||||
#define DAYSTO100NSECS(days) (((ULONGLONG)(days))*24*60*60*10000000)
|
#define DAYSTO100NSECS(days) (((ULONGLONG)(days))*24*60*60*10000000)
|
||||||
|
|
||||||
|
enum CachedPen
|
||||||
|
{
|
||||||
|
PenRed = 0,
|
||||||
|
PenText,
|
||||||
|
PenLast
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CachedBrush
|
||||||
|
{
|
||||||
|
BrushTitle = 0,
|
||||||
|
BrushMonth,
|
||||||
|
BrushBackground,
|
||||||
|
BrushLast
|
||||||
|
};
|
||||||
|
|
||||||
/* single calendar data */
|
/* single calendar data */
|
||||||
typedef struct _CALENDAR_INFO
|
typedef struct _CALENDAR_INFO
|
||||||
{
|
{
|
||||||
|
@ -96,6 +110,8 @@ typedef struct
|
||||||
DWORD dwStyle; /* cached GWL_STYLE */
|
DWORD dwStyle; /* cached GWL_STYLE */
|
||||||
|
|
||||||
COLORREF colors[MCSC_TRAILINGTEXT+1];
|
COLORREF colors[MCSC_TRAILINGTEXT+1];
|
||||||
|
HBRUSH brushes[BrushLast];
|
||||||
|
HPEN pens[PenLast];
|
||||||
|
|
||||||
HFONT hFont;
|
HFONT hFont;
|
||||||
HFONT hBoldFont;
|
HFONT hBoldFont;
|
||||||
|
@ -143,8 +159,8 @@ static const WCHAR themeClass[] = { 'S','c','r','o','l','l','b','a','r',0 };
|
||||||
/* empty SYSTEMTIME const */
|
/* empty SYSTEMTIME const */
|
||||||
static const SYSTEMTIME st_null;
|
static const SYSTEMTIME st_null;
|
||||||
/* valid date limits */
|
/* valid date limits */
|
||||||
static const SYSTEMTIME max_allowed_date = { 9999, 12, 0, 31, 0, 0, 0, 0 };
|
static const SYSTEMTIME max_allowed_date = { .wYear = 9999, .wMonth = 12, .wDay = 31 };
|
||||||
static const SYSTEMTIME min_allowed_date = { 1752, 9, 0, 14, 0, 0, 0, 0 };
|
static const SYSTEMTIME min_allowed_date = { .wYear = 1752, .wMonth = 9, .wDay = 14 };
|
||||||
|
|
||||||
/* Prev/Next buttons */
|
/* Prev/Next buttons */
|
||||||
enum nav_direction
|
enum nav_direction
|
||||||
|
@ -449,7 +465,7 @@ int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace)
|
||||||
return st.wDayOfWeek;
|
return st.wDayOfWeek;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add/substract 'months' from date */
|
/* add/subtract 'months' from date */
|
||||||
static inline void MONTHCAL_GetMonth(SYSTEMTIME *date, INT months)
|
static inline void MONTHCAL_GetMonth(SYSTEMTIME *date, INT months)
|
||||||
{
|
{
|
||||||
INT length, m = date->wMonth + months;
|
INT length, m = date->wMonth + months;
|
||||||
|
@ -636,28 +652,31 @@ static BOOL MONTHCAL_SetDayFocus(MONTHCAL_INFO *infoPtr, const SYSTEMTIME *st)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* draw today boundary box for specified rectangle */
|
||||||
|
static void MONTHCAL_Circle(const MONTHCAL_INFO *infoPtr, HDC hdc, const RECT *r)
|
||||||
|
{
|
||||||
|
HPEN old_pen = SelectObject(hdc, infoPtr->pens[PenRed]);
|
||||||
|
HBRUSH old_brush;
|
||||||
|
|
||||||
|
old_brush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
||||||
|
Rectangle(hdc, r->left, r->top, r->right, r->bottom);
|
||||||
|
|
||||||
|
SelectObject(hdc, old_brush);
|
||||||
|
SelectObject(hdc, old_pen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw today day mark rectangle
|
/* Draw today day mark rectangle
|
||||||
*
|
*
|
||||||
* [I] hdc : context to draw in
|
* [I] hdc : context to draw in
|
||||||
* [I] day : day to mark with rectangle
|
* [I] date : day to mark with rectangle
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void MONTHCAL_CircleDay(const MONTHCAL_INFO *infoPtr, HDC hdc,
|
static void MONTHCAL_CircleDay(const MONTHCAL_INFO *infoPtr, HDC hdc,
|
||||||
const SYSTEMTIME *date)
|
const SYSTEMTIME *date)
|
||||||
{
|
{
|
||||||
HPEN hRedPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
|
|
||||||
HPEN hOldPen2 = SelectObject(hdc, hRedPen);
|
|
||||||
HBRUSH hOldBrush;
|
|
||||||
RECT day_rect;
|
RECT day_rect;
|
||||||
|
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, date, &day_rect);
|
MONTHCAL_CalcPosFromDay(infoPtr, date, &day_rect);
|
||||||
|
MONTHCAL_Circle(infoPtr, hdc, &day_rect);
|
||||||
hOldBrush = SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
|
||||||
Rectangle(hdc, day_rect.left, day_rect.top, day_rect.right, day_rect.bottom);
|
|
||||||
|
|
||||||
SelectObject(hdc, hOldBrush);
|
|
||||||
DeleteObject(hRedPen);
|
|
||||||
SelectObject(hdc, hOldPen2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MONTHCAL_DrawDay(const MONTHCAL_INFO *infoPtr, HDC hdc, const SYSTEMTIME *st,
|
static void MONTHCAL_DrawDay(const MONTHCAL_INFO *infoPtr, HDC hdc, const SYSTEMTIME *st,
|
||||||
|
@ -666,46 +685,39 @@ static void MONTHCAL_DrawDay(const MONTHCAL_INFO *infoPtr, HDC hdc, const SYSTEM
|
||||||
static const WCHAR fmtW[] = { '%','d',0 };
|
static const WCHAR fmtW[] = { '%','d',0 };
|
||||||
WCHAR buf[10];
|
WCHAR buf[10];
|
||||||
RECT r, r_temp;
|
RECT r, r_temp;
|
||||||
static BOOL bold_selected;
|
|
||||||
BOOL selected_day = FALSE;
|
|
||||||
HBRUSH hbr;
|
|
||||||
COLORREF oldCol = 0;
|
COLORREF oldCol = 0;
|
||||||
COLORREF oldBk = 0;
|
COLORREF oldBk = 0;
|
||||||
|
INT old_bkmode, selection;
|
||||||
|
|
||||||
/* No need to check styles: when selection is not valid, it is set to zero.
|
/* no need to check styles: when selection is not valid, it is set to zero.
|
||||||
* 1<day<31, so everything is OK.
|
1 < day < 31, so everything is OK */
|
||||||
*/
|
|
||||||
|
|
||||||
MONTHCAL_CalcPosFromDay(infoPtr, st, &r);
|
MONTHCAL_CalcPosFromDay(infoPtr, st, &r);
|
||||||
if(!IntersectRect(&r_temp, &(ps->rcPaint), &r)) return;
|
if(!IntersectRect(&r_temp, &(ps->rcPaint), &r)) return;
|
||||||
|
|
||||||
if ((MONTHCAL_CompareDate(st, &infoPtr->minSel) >= 0) &&
|
if ((MONTHCAL_CompareDate(st, &infoPtr->minSel) >= 0) &&
|
||||||
(MONTHCAL_CompareDate(st, &infoPtr->maxSel) <= 0)) {
|
(MONTHCAL_CompareDate(st, &infoPtr->maxSel) <= 0))
|
||||||
|
{
|
||||||
|
|
||||||
TRACE("%d %d %d\n", st->wDay, infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
|
TRACE("%d %d %d\n", st->wDay, infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
|
||||||
TRACE("%s\n", wine_dbgstr_rect(&r));
|
TRACE("%s\n", wine_dbgstr_rect(&r));
|
||||||
oldCol = SetTextColor(hdc, infoPtr->colors[MCSC_MONTHBK]);
|
oldCol = SetTextColor(hdc, infoPtr->colors[MCSC_MONTHBK]);
|
||||||
oldBk = SetBkColor(hdc, infoPtr->colors[MCSC_TRAILINGTEXT]);
|
oldBk = SetBkColor(hdc, infoPtr->colors[MCSC_TRAILINGTEXT]);
|
||||||
hbr = GetSysColorBrush(COLOR_HIGHLIGHT);
|
FillRect(hdc, &r, infoPtr->brushes[BrushTitle]);
|
||||||
FillRect(hdc, &r, hbr);
|
|
||||||
|
|
||||||
selected_day = TRUE;
|
selection = 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
selection = 0;
|
||||||
|
|
||||||
if(bold && !bold_selected) {
|
SelectObject(hdc, bold ? infoPtr->hBoldFont : infoPtr->hFont);
|
||||||
SelectObject(hdc, infoPtr->hBoldFont);
|
|
||||||
bold_selected = TRUE;
|
|
||||||
}
|
|
||||||
if(!bold && bold_selected) {
|
|
||||||
SelectObject(hdc, infoPtr->hFont);
|
|
||||||
bold_selected = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetBkMode(hdc,TRANSPARENT);
|
old_bkmode = SetBkMode(hdc, TRANSPARENT);
|
||||||
wsprintfW(buf, fmtW, st->wDay);
|
wsprintfW(buf, fmtW, st->wDay);
|
||||||
DrawTextW(hdc, buf, -1, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
|
DrawTextW(hdc, buf, -1, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
|
||||||
|
SetBkMode(hdc, old_bkmode);
|
||||||
|
|
||||||
if(selected_day) {
|
if (selection)
|
||||||
|
{
|
||||||
SetTextColor(hdc, oldCol);
|
SetTextColor(hdc, oldCol);
|
||||||
SetBkColor(hdc, oldBk);
|
SetBkColor(hdc, oldBk);
|
||||||
}
|
}
|
||||||
|
@ -755,13 +767,10 @@ static void MONTHCAL_PaintTitle(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRU
|
||||||
RECT *title = &infoPtr->calendars[calIdx].title;
|
RECT *title = &infoPtr->calendars[calIdx].title;
|
||||||
const SYSTEMTIME *st = &infoPtr->calendars[calIdx].month;
|
const SYSTEMTIME *st = &infoPtr->calendars[calIdx].month;
|
||||||
WCHAR buf_month[80], buf_fmt[80];
|
WCHAR buf_month[80], buf_fmt[80];
|
||||||
HBRUSH hbr;
|
|
||||||
SIZE sz;
|
SIZE sz;
|
||||||
|
|
||||||
/* fill header box */
|
/* fill header box */
|
||||||
hbr = CreateSolidBrush(infoPtr->colors[MCSC_TITLEBK]);
|
FillRect(hdc, title, infoPtr->brushes[BrushTitle]);
|
||||||
FillRect(hdc, title, hbr);
|
|
||||||
DeleteObject(hbr);
|
|
||||||
|
|
||||||
/* month/year string */
|
/* month/year string */
|
||||||
SetBkColor(hdc, infoPtr->colors[MCSC_TITLEBK]);
|
SetBkColor(hdc, infoPtr->colors[MCSC_TITLEBK]);
|
||||||
|
@ -793,7 +802,7 @@ static void MONTHCAL_PaintWeeknumbers(const MONTHCAL_INFO *infoPtr, HDC hdc, con
|
||||||
INT i, prev_month;
|
INT i, prev_month;
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
WCHAR buf[80];
|
WCHAR buf[80];
|
||||||
HBRUSH hbr;
|
HPEN old_pen;
|
||||||
RECT r;
|
RECT r;
|
||||||
|
|
||||||
if (!(infoPtr->dwStyle & MCS_WEEKNUMBERS)) return;
|
if (!(infoPtr->dwStyle & MCS_WEEKNUMBERS)) return;
|
||||||
|
@ -865,9 +874,8 @@ static void MONTHCAL_PaintWeeknumbers(const MONTHCAL_INFO *infoPtr, HDC hdc, con
|
||||||
r = infoPtr->calendars[calIdx].weeknums;
|
r = infoPtr->calendars[calIdx].weeknums;
|
||||||
|
|
||||||
/* erase whole week numbers area */
|
/* erase whole week numbers area */
|
||||||
hbr = CreateSolidBrush(infoPtr->colors[MCSC_MONTHBK]);
|
FillRect(hdc, &r, infoPtr->brushes[BrushTitle]);
|
||||||
FillRect(hdc, &r, hbr);
|
SetTextColor(hdc, infoPtr->colors[MCSC_TITLEBK]);
|
||||||
DeleteObject(hbr);
|
|
||||||
|
|
||||||
/* reduce rectangle to one week number */
|
/* reduce rectangle to one week number */
|
||||||
r.bottom = r.top + infoPtr->height_increment;
|
r.bottom = r.top + infoPtr->height_increment;
|
||||||
|
@ -890,43 +898,50 @@ static void MONTHCAL_PaintWeeknumbers(const MONTHCAL_INFO *infoPtr, HDC hdc, con
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line separator for week numbers column */
|
/* line separator for week numbers column */
|
||||||
|
old_pen = SelectObject(hdc, infoPtr->pens[PenText]);
|
||||||
MoveToEx(hdc, infoPtr->calendars[calIdx].weeknums.right, infoPtr->calendars[calIdx].weeknums.top + 3 , NULL);
|
MoveToEx(hdc, infoPtr->calendars[calIdx].weeknums.right, infoPtr->calendars[calIdx].weeknums.top + 3 , NULL);
|
||||||
LineTo(hdc, infoPtr->calendars[calIdx].weeknums.right, infoPtr->calendars[calIdx].weeknums.bottom);
|
LineTo(hdc, infoPtr->calendars[calIdx].weeknums.right, infoPtr->calendars[calIdx].weeknums.bottom);
|
||||||
|
SelectObject(hdc, old_pen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bottom today date */
|
/* bottom today date */
|
||||||
static void MONTHCAL_PaintTodayTitle(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
|
static void MONTHCAL_PaintTodayTitle(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
|
||||||
{
|
{
|
||||||
if(!(infoPtr->dwStyle & MCS_NOTODAY)) {
|
static const WCHAR fmt_todayW[] = { '%','s',' ','%','s',0 };
|
||||||
|
WCHAR buf_todayW[30], buf_dateW[20], buf[80];
|
||||||
|
RECT text_rect, box_rect;
|
||||||
|
HFONT old_font;
|
||||||
|
INT col;
|
||||||
|
|
||||||
|
if(infoPtr->dwStyle & MCS_NOTODAY) return;
|
||||||
|
|
||||||
|
if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW)))
|
||||||
|
{
|
||||||
static const WCHAR todayW[] = { 'T','o','d','a','y',':',0 };
|
static const WCHAR todayW[] = { 'T','o','d','a','y',':',0 };
|
||||||
static const WCHAR fmt_todayW[] = { '%','s',' ','%','s',0 };
|
WARN("Can't load resource\n");
|
||||||
WCHAR buf_todayW[30], buf_dateW[20], buf[80];
|
strcpyW(buf_todayW, todayW);
|
||||||
RECT rtoday;
|
|
||||||
|
|
||||||
if(!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE)) {
|
|
||||||
SYSTEMTIME fake_st;
|
|
||||||
|
|
||||||
MONTHCAL_GetMaxDate(infoPtr, &fake_st);
|
|
||||||
/* this is always safe cause next month will never fully fit calendar */
|
|
||||||
fake_st.wDay += 1;
|
|
||||||
MONTHCAL_CircleDay(infoPtr, hdc, &fake_st);
|
|
||||||
}
|
|
||||||
if (!LoadStringW(COMCTL32_hModule, IDM_TODAY, buf_todayW, countof(buf_todayW)))
|
|
||||||
{
|
|
||||||
WARN("Can't load resource\n");
|
|
||||||
strcpyW(buf_todayW, todayW);
|
|
||||||
}
|
|
||||||
MONTHCAL_CalcDayRect(infoPtr, &rtoday, 1, 6);
|
|
||||||
GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &infoPtr->todaysDate, NULL,
|
|
||||||
buf_dateW, countof(buf_dateW));
|
|
||||||
SelectObject(hdc, infoPtr->hBoldFont);
|
|
||||||
|
|
||||||
wsprintfW(buf, fmt_todayW, buf_todayW, buf_dateW);
|
|
||||||
DrawTextW(hdc, buf, -1, &rtoday, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
|
||||||
DrawTextW(hdc, buf, -1, &rtoday, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
|
||||||
|
|
||||||
SelectObject(hdc, infoPtr->hFont);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
col = infoPtr->dwStyle & MCS_NOTODAYCIRCLE ? 0 : 1;
|
||||||
|
if (infoPtr->dwStyle & MCS_WEEKNUMBERS) col--;
|
||||||
|
MONTHCAL_CalcDayRect(infoPtr, &text_rect, col, 6);
|
||||||
|
box_rect = text_rect;
|
||||||
|
|
||||||
|
GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &infoPtr->todaysDate, NULL,
|
||||||
|
buf_dateW, countof(buf_dateW));
|
||||||
|
old_font = SelectObject(hdc, infoPtr->hBoldFont);
|
||||||
|
SetTextColor(hdc, infoPtr->colors[MCSC_TEXT]);
|
||||||
|
|
||||||
|
wsprintfW(buf, fmt_todayW, buf_todayW, buf_dateW);
|
||||||
|
DrawTextW(hdc, buf, -1, &text_rect, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
||||||
|
DrawTextW(hdc, buf, -1, &text_rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
||||||
|
|
||||||
|
if(!(infoPtr->dwStyle & MCS_NOTODAYCIRCLE)) {
|
||||||
|
OffsetRect(&box_rect, -infoPtr->width_increment, 0);
|
||||||
|
MONTHCAL_Circle(infoPtr, hdc, &box_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectObject(hdc, old_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* today mark + focus */
|
/* today mark + focus */
|
||||||
|
@ -947,15 +962,53 @@ static void MONTHCAL_PaintFocusAndCircle(const MONTHCAL_INFO *infoPtr, HDC hdc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* months before first calendar month and after last calendar month */
|
||||||
|
static void MONTHCAL_PaintLeadTrailMonths(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps)
|
||||||
|
{
|
||||||
|
INT mask, length;
|
||||||
|
SYSTEMTIME st_max, st;
|
||||||
|
|
||||||
|
if (infoPtr->dwStyle & MCS_NOTRAILINGDATES) return;
|
||||||
|
|
||||||
|
SetTextColor(hdc, infoPtr->colors[MCSC_TRAILINGTEXT]);
|
||||||
|
|
||||||
|
/* draw prev month */
|
||||||
|
MONTHCAL_GetMinDate(infoPtr, &st);
|
||||||
|
mask = 1 << (st.wDay-1);
|
||||||
|
/* December and January both 31 days long, so no worries if wrapped */
|
||||||
|
length = MONTHCAL_MonthLength(infoPtr->calendars[0].month.wMonth - 1,
|
||||||
|
infoPtr->calendars[0].month.wYear);
|
||||||
|
while(st.wDay <= length)
|
||||||
|
{
|
||||||
|
MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[0] & mask, ps);
|
||||||
|
mask <<= 1;
|
||||||
|
st.wDay++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw next month */
|
||||||
|
st = infoPtr->calendars[infoPtr->cal_num-1].month;
|
||||||
|
st.wDay = 1;
|
||||||
|
MONTHCAL_GetNextMonth(&st);
|
||||||
|
MONTHCAL_GetMaxDate(infoPtr, &st_max);
|
||||||
|
mask = 1;
|
||||||
|
|
||||||
|
while(st.wDay <= st_max.wDay)
|
||||||
|
{
|
||||||
|
MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[2] & mask, ps);
|
||||||
|
mask <<= 1;
|
||||||
|
st.wDay++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* paint a calendar area */
|
/* paint a calendar area */
|
||||||
static void MONTHCAL_PaintCalendar(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
|
static void MONTHCAL_PaintCalendar(const MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT *ps, INT calIdx)
|
||||||
{
|
{
|
||||||
const SYSTEMTIME *date = &infoPtr->calendars[calIdx].month;
|
const SYSTEMTIME *date = &infoPtr->calendars[calIdx].month;
|
||||||
INT prev_month, i, j, length;
|
INT i, j, length;
|
||||||
RECT r, fill_bk_rect;
|
RECT r, fill_bk_rect;
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
WCHAR buf[80];
|
WCHAR buf[80];
|
||||||
HBRUSH hbr;
|
HPEN old_pen;
|
||||||
int mask;
|
int mask;
|
||||||
|
|
||||||
/* fill whole days area - from week days area to today note rectangle */
|
/* fill whole days area - from week days area to today note rectangle */
|
||||||
|
@ -963,26 +1016,23 @@ static void MONTHCAL_PaintCalendar(const MONTHCAL_INFO *infoPtr, HDC hdc, const
|
||||||
fill_bk_rect.bottom = infoPtr->calendars[calIdx].days.bottom +
|
fill_bk_rect.bottom = infoPtr->calendars[calIdx].days.bottom +
|
||||||
(infoPtr->todayrect.bottom - infoPtr->todayrect.top);
|
(infoPtr->todayrect.bottom - infoPtr->todayrect.top);
|
||||||
|
|
||||||
hbr = CreateSolidBrush(infoPtr->colors[MCSC_MONTHBK]);
|
FillRect(hdc, &fill_bk_rect, infoPtr->brushes[BrushMonth]);
|
||||||
FillRect(hdc, &fill_bk_rect, hbr);
|
|
||||||
DeleteObject(hbr);
|
|
||||||
|
|
||||||
/* draw line under day abbreviations */
|
/* draw line under day abbreviations */
|
||||||
|
old_pen = SelectObject(hdc, infoPtr->pens[PenText]);
|
||||||
MoveToEx(hdc, infoPtr->calendars[calIdx].days.left + 3,
|
MoveToEx(hdc, infoPtr->calendars[calIdx].days.left + 3,
|
||||||
infoPtr->calendars[calIdx].title.bottom + infoPtr->textHeight + 1, NULL);
|
infoPtr->calendars[calIdx].title.bottom + infoPtr->textHeight + 1, NULL);
|
||||||
LineTo(hdc, infoPtr->calendars[calIdx].days.right - 3,
|
LineTo(hdc, infoPtr->calendars[calIdx].days.right - 3,
|
||||||
infoPtr->calendars[calIdx].title.bottom + infoPtr->textHeight + 1);
|
infoPtr->calendars[calIdx].title.bottom + infoPtr->textHeight + 1);
|
||||||
|
SelectObject(hdc, old_pen);
|
||||||
prev_month = date->wMonth - 1;
|
|
||||||
if (prev_month == 0) prev_month = 12;
|
|
||||||
|
|
||||||
infoPtr->calendars[calIdx].wdays.left = infoPtr->calendars[calIdx].days.left =
|
infoPtr->calendars[calIdx].wdays.left = infoPtr->calendars[calIdx].days.left =
|
||||||
infoPtr->calendars[calIdx].weeknums.right;
|
infoPtr->calendars[calIdx].weeknums.right;
|
||||||
|
|
||||||
/* 1. draw day abbreviations */
|
/* draw day abbreviations */
|
||||||
SelectObject(hdc, infoPtr->hFont);
|
SelectObject(hdc, infoPtr->hFont);
|
||||||
SetBkColor(hdc, infoPtr->colors[MCSC_MONTHBK]);
|
SetBkColor(hdc, infoPtr->colors[MCSC_MONTHBK]);
|
||||||
SetTextColor(hdc, infoPtr->colors[MCSC_TRAILINGTEXT]);
|
SetTextColor(hdc, infoPtr->colors[MCSC_TITLEBK]);
|
||||||
/* rectangle to draw a single day abbreviation within */
|
/* rectangle to draw a single day abbreviation within */
|
||||||
r = infoPtr->calendars[calIdx].wdays;
|
r = infoPtr->calendars[calIdx].wdays;
|
||||||
r.right = r.left + infoPtr->width_increment;
|
r.right = r.left + infoPtr->width_increment;
|
||||||
|
@ -994,47 +1044,7 @@ static void MONTHCAL_PaintCalendar(const MONTHCAL_INFO *infoPtr, HDC hdc, const
|
||||||
OffsetRect(&r, infoPtr->width_increment, 0);
|
OffsetRect(&r, infoPtr->width_increment, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. previous and next months */
|
/* draw current month */
|
||||||
if (!(infoPtr->dwStyle & MCS_NOTRAILINGDATES) && (calIdx == 0 || calIdx == infoPtr->cal_num - 1))
|
|
||||||
{
|
|
||||||
SYSTEMTIME st_max;
|
|
||||||
|
|
||||||
SetTextColor(hdc, infoPtr->colors[MCSC_TRAILINGTEXT]);
|
|
||||||
|
|
||||||
/* draw prev month */
|
|
||||||
if (calIdx == 0)
|
|
||||||
{
|
|
||||||
MONTHCAL_GetMinDate(infoPtr, &st);
|
|
||||||
mask = 1 << (st.wDay-1);
|
|
||||||
length = MONTHCAL_MonthLength(prev_month, date->wYear);
|
|
||||||
|
|
||||||
while(st.wDay <= length)
|
|
||||||
{
|
|
||||||
MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[0] & mask, ps);
|
|
||||||
mask <<= 1;
|
|
||||||
st.wDay++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* draw next month */
|
|
||||||
if (calIdx == infoPtr->cal_num - 1)
|
|
||||||
{
|
|
||||||
st = *date;
|
|
||||||
st.wDay = 1;
|
|
||||||
MONTHCAL_GetNextMonth(&st);
|
|
||||||
MONTHCAL_GetMaxDate(infoPtr, &st_max);
|
|
||||||
mask = 1;
|
|
||||||
|
|
||||||
while(st.wDay <= st_max.wDay)
|
|
||||||
{
|
|
||||||
MONTHCAL_DrawDay(infoPtr, hdc, &st, infoPtr->monthdayState[2] & mask, ps);
|
|
||||||
mask <<= 1;
|
|
||||||
st.wDay++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 3. current month */
|
|
||||||
SetTextColor(hdc, infoPtr->colors[MCSC_TEXT]);
|
SetTextColor(hdc, infoPtr->colors[MCSC_TEXT]);
|
||||||
st = *date;
|
st = *date;
|
||||||
st.wDay = 1;
|
st.wDay = 1;
|
||||||
|
@ -1076,6 +1086,9 @@ static void MONTHCAL_Refresh(MONTHCAL_INFO *infoPtr, HDC hdc, const PAINTSTRUCT
|
||||||
MONTHCAL_PaintWeeknumbers(infoPtr, hdc, ps, i);
|
MONTHCAL_PaintWeeknumbers(infoPtr, hdc, ps, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* partially visible months */
|
||||||
|
MONTHCAL_PaintLeadTrailMonths(infoPtr, hdc, ps);
|
||||||
|
|
||||||
/* focus and today rectangle */
|
/* focus and today rectangle */
|
||||||
MONTHCAL_PaintFocusAndCircle(infoPtr, hdc, ps);
|
MONTHCAL_PaintFocusAndCircle(infoPtr, hdc, ps);
|
||||||
|
|
||||||
|
@ -1125,6 +1138,7 @@ MONTHCAL_GetColor(const MONTHCAL_INFO *infoPtr, UINT index)
|
||||||
static LRESULT
|
static LRESULT
|
||||||
MONTHCAL_SetColor(MONTHCAL_INFO *infoPtr, UINT index, COLORREF color)
|
MONTHCAL_SetColor(MONTHCAL_INFO *infoPtr, UINT index, COLORREF color)
|
||||||
{
|
{
|
||||||
|
enum CachedBrush type;
|
||||||
COLORREF prev;
|
COLORREF prev;
|
||||||
|
|
||||||
TRACE("%p, %d: color %08x\n", infoPtr, index, color);
|
TRACE("%p, %d: color %08x\n", infoPtr, index, color);
|
||||||
|
@ -1134,6 +1148,35 @@ MONTHCAL_SetColor(MONTHCAL_INFO *infoPtr, UINT index, COLORREF color)
|
||||||
prev = infoPtr->colors[index];
|
prev = infoPtr->colors[index];
|
||||||
infoPtr->colors[index] = color;
|
infoPtr->colors[index] = color;
|
||||||
|
|
||||||
|
/* update cached brush */
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case MCSC_BACKGROUND:
|
||||||
|
type = BrushBackground;
|
||||||
|
break;
|
||||||
|
case MCSC_TITLEBK:
|
||||||
|
type = BrushTitle;
|
||||||
|
break;
|
||||||
|
case MCSC_MONTHBK:
|
||||||
|
type = BrushMonth;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = BrushLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type != BrushLast)
|
||||||
|
{
|
||||||
|
DeleteObject(infoPtr->brushes[type]);
|
||||||
|
infoPtr->brushes[type] = CreateSolidBrush(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update cached pen */
|
||||||
|
if (index == MCSC_TEXT)
|
||||||
|
{
|
||||||
|
DeleteObject(infoPtr->pens[PenText]);
|
||||||
|
infoPtr->pens[PenText] = CreatePen(PS_SOLID, 1, infoPtr->colors[index]);
|
||||||
|
}
|
||||||
|
|
||||||
InvalidateRect(infoPtr->hwndSelf, NULL, index == MCSC_BACKGROUND ? TRUE : FALSE);
|
InvalidateRect(infoPtr->hwndSelf, NULL, index == MCSC_BACKGROUND ? TRUE : FALSE);
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
@ -1265,8 +1308,6 @@ MONTHCAL_GetMonthRange(const MONTHCAL_INFO *infoPtr, DWORD flag, SYSTEMTIME *st)
|
||||||
}
|
}
|
||||||
case GMR_DAYSTATE:
|
case GMR_DAYSTATE:
|
||||||
{
|
{
|
||||||
/*FIXME: currently multicalendar feature isn't implemented,
|
|
||||||
min date from previous month and max date from next one returned */
|
|
||||||
MONTHCAL_GetMinDate(infoPtr, &st[0]);
|
MONTHCAL_GetMinDate(infoPtr, &st[0]);
|
||||||
MONTHCAL_GetMaxDate(infoPtr, &st[1]);
|
MONTHCAL_GetMaxDate(infoPtr, &st[1]);
|
||||||
break;
|
break;
|
||||||
|
@ -1727,7 +1768,7 @@ MONTHCAL_HitTest(const MONTHCAL_INFO *infoPtr, MCHITTESTINFO *lpht)
|
||||||
{
|
{
|
||||||
htinfo.uHit = MCHT_CALENDARDATEPREV;
|
htinfo.uHit = MCHT_CALENDARDATEPREV;
|
||||||
MONTHCAL_GetPrevMonth(&htinfo.st);
|
MONTHCAL_GetPrevMonth(&htinfo.st);
|
||||||
htinfo.st.wDay = MONTHCAL_MonthLength(lpht->st.wMonth, lpht->st.wYear) + day;
|
htinfo.st.wDay = MONTHCAL_MonthLength(htinfo.st.wMonth, htinfo.st.wYear) + day;
|
||||||
}
|
}
|
||||||
else if (day > MONTHCAL_MonthLength(ht_month.wMonth, ht_month.wYear))
|
else if (day > MONTHCAL_MonthLength(ht_month.wMonth, ht_month.wYear))
|
||||||
{
|
{
|
||||||
|
@ -2237,15 +2278,11 @@ MONTHCAL_Paint(MONTHCAL_INFO *infoPtr, HDC hdc_paint)
|
||||||
static LRESULT
|
static LRESULT
|
||||||
MONTHCAL_EraseBkgnd(const MONTHCAL_INFO *infoPtr, HDC hdc)
|
MONTHCAL_EraseBkgnd(const MONTHCAL_INFO *infoPtr, HDC hdc)
|
||||||
{
|
{
|
||||||
HBRUSH hbr;
|
|
||||||
RECT rc;
|
RECT rc;
|
||||||
|
|
||||||
if (!GetClipBox(hdc, &rc)) return FALSE;
|
if (!GetClipBox(hdc, &rc)) return FALSE;
|
||||||
|
|
||||||
/* fill background */
|
FillRect(hdc, &rc, infoPtr->brushes[BrushBackground]);
|
||||||
hbr = CreateSolidBrush (infoPtr->colors[MCSC_BACKGROUND]);
|
|
||||||
FillRect(hdc, &rc, hbr);
|
|
||||||
DeleteObject(hbr);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2520,7 +2557,7 @@ MONTHCAL_Create(HWND hwnd, LPCREATESTRUCTW lpcs)
|
||||||
MONTHCAL_SetFont(infoPtr, GetStockObject(DEFAULT_GUI_FONT), FALSE);
|
MONTHCAL_SetFont(infoPtr, GetStockObject(DEFAULT_GUI_FONT), FALSE);
|
||||||
|
|
||||||
/* initialize info structure */
|
/* initialize info structure */
|
||||||
/* FIXME: calculate systemtime ->> localtime(substract timezoneinfo) */
|
/* FIXME: calculate systemtime ->> localtime(subtract timezoneinfo) */
|
||||||
|
|
||||||
GetLocalTime(&infoPtr->todaysDate);
|
GetLocalTime(&infoPtr->todaysDate);
|
||||||
MONTHCAL_SetFirstDayOfWeek(infoPtr, -1);
|
MONTHCAL_SetFirstDayOfWeek(infoPtr, -1);
|
||||||
|
@ -2538,6 +2575,13 @@ MONTHCAL_Create(HWND hwnd, LPCREATESTRUCTW lpcs)
|
||||||
infoPtr->colors[MCSC_MONTHBK] = comctl32_color.clrWindow;
|
infoPtr->colors[MCSC_MONTHBK] = comctl32_color.clrWindow;
|
||||||
infoPtr->colors[MCSC_TRAILINGTEXT] = comctl32_color.clrGrayText;
|
infoPtr->colors[MCSC_TRAILINGTEXT] = comctl32_color.clrGrayText;
|
||||||
|
|
||||||
|
infoPtr->brushes[BrushBackground] = CreateSolidBrush(infoPtr->colors[MCSC_BACKGROUND]);
|
||||||
|
infoPtr->brushes[BrushTitle] = CreateSolidBrush(infoPtr->colors[MCSC_TITLEBK]);
|
||||||
|
infoPtr->brushes[BrushMonth] = CreateSolidBrush(infoPtr->colors[MCSC_MONTHBK]);
|
||||||
|
|
||||||
|
infoPtr->pens[PenRed] = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
|
||||||
|
infoPtr->pens[PenText] = CreatePen(PS_SOLID, 1, infoPtr->colors[MCSC_TEXT]);
|
||||||
|
|
||||||
infoPtr->minSel = infoPtr->todaysDate;
|
infoPtr->minSel = infoPtr->todaysDate;
|
||||||
infoPtr->maxSel = infoPtr->todaysDate;
|
infoPtr->maxSel = infoPtr->todaysDate;
|
||||||
infoPtr->calendars[0].month = infoPtr->todaysDate;
|
infoPtr->calendars[0].month = infoPtr->todaysDate;
|
||||||
|
@ -2564,13 +2608,18 @@ fail:
|
||||||
static LRESULT
|
static LRESULT
|
||||||
MONTHCAL_Destroy(MONTHCAL_INFO *infoPtr)
|
MONTHCAL_Destroy(MONTHCAL_INFO *infoPtr)
|
||||||
{
|
{
|
||||||
|
INT i;
|
||||||
|
|
||||||
/* free month calendar info data */
|
/* free month calendar info data */
|
||||||
Free(infoPtr->monthdayState);
|
Free(infoPtr->monthdayState);
|
||||||
Free(infoPtr->calendars);
|
Free(infoPtr->calendars);
|
||||||
SetWindowLongPtrW(infoPtr->hwndSelf, 0, 0);
|
SetWindowLongPtrW(infoPtr->hwndSelf, 0, 0);
|
||||||
|
|
||||||
CloseThemeData (GetWindowTheme (infoPtr->hwndSelf));
|
CloseThemeData (GetWindowTheme (infoPtr->hwndSelf));
|
||||||
|
|
||||||
|
for (i = 0; i < BrushLast; i++) DeleteObject(infoPtr->brushes[i]);
|
||||||
|
for (i = 0; i < PenLast; i++) DeleteObject(infoPtr->pens[i]);
|
||||||
|
|
||||||
Free(infoPtr);
|
Free(infoPtr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2490,7 +2490,7 @@ static void PROPSHEET_SetWizButtons(HWND hwndDlg, DWORD dwFlags)
|
||||||
{
|
{
|
||||||
SendMessageW(hwndDlg, DM_SETDEFID, IDC_FINISH_BUTTON, 0);
|
SendMessageW(hwndDlg, DM_SETDEFID, IDC_FINISH_BUTTON, 0);
|
||||||
SetFocus(hwndFinish);
|
SetFocus(hwndFinish);
|
||||||
}
|
}
|
||||||
else if (dwFlags & PSWIZB_NEXT)
|
else if (dwFlags & PSWIZB_NEXT)
|
||||||
{
|
{
|
||||||
SendMessageW(hwndDlg, DM_SETDEFID, IDC_NEXT_BUTTON, 0);
|
SendMessageW(hwndDlg, DM_SETDEFID, IDC_NEXT_BUTTON, 0);
|
||||||
|
|
|
@ -661,10 +661,12 @@ static BOOL
|
||||||
STATUSBAR_SetParts (STATUS_INFO *infoPtr, INT count, LPINT parts)
|
STATUSBAR_SetParts (STATUS_INFO *infoPtr, INT count, LPINT parts)
|
||||||
{
|
{
|
||||||
STATUSWINDOWPART *tmp;
|
STATUSWINDOWPART *tmp;
|
||||||
UINT i, oldNumParts;
|
INT i, oldNumParts;
|
||||||
|
|
||||||
TRACE("(%d,%p)\n", count, parts);
|
TRACE("(%d,%p)\n", count, parts);
|
||||||
|
|
||||||
|
if(!count) return FALSE;
|
||||||
|
|
||||||
oldNumParts = infoPtr->numParts;
|
oldNumParts = infoPtr->numParts;
|
||||||
infoPtr->numParts = count;
|
infoPtr->numParts = count;
|
||||||
if (oldNumParts > infoPtr->numParts) {
|
if (oldNumParts > infoPtr->numParts) {
|
||||||
|
@ -693,7 +695,7 @@ STATUSBAR_SetParts (STATUS_INFO *infoPtr, INT count, LPINT parts)
|
||||||
infoPtr->parts[i].x = parts[i];
|
infoPtr->parts[i].x = parts[i];
|
||||||
|
|
||||||
if (infoPtr->hwndToolTip) {
|
if (infoPtr->hwndToolTip) {
|
||||||
UINT nTipCount;
|
INT nTipCount;
|
||||||
TTTOOLINFOW ti;
|
TTTOOLINFOW ti;
|
||||||
|
|
||||||
ZeroMemory (&ti, sizeof(TTTOOLINFOW));
|
ZeroMemory (&ti, sizeof(TTTOOLINFOW));
|
||||||
|
|
|
@ -529,7 +529,7 @@ static PDOC_ITEM SYSLINK_GetFocusLink (const SYSLINK_INFO *infoPtr, int *LinkId)
|
||||||
|
|
||||||
while(Current != NULL)
|
while(Current != NULL)
|
||||||
{
|
{
|
||||||
if((Current->Type == slLink))
|
if(Current->Type == slLink)
|
||||||
{
|
{
|
||||||
if(Current->u.Link.state & LIS_FOCUSED)
|
if(Current->u.Link.state & LIS_FOCUSED)
|
||||||
{
|
{
|
||||||
|
@ -1564,7 +1564,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
|
||||||
infoPtr = (SYSLINK_INFO *)GetWindowLongPtrW(hwnd, 0);
|
infoPtr = (SYSLINK_INFO *)GetWindowLongPtrW(hwnd, 0);
|
||||||
|
|
||||||
if (!infoPtr && message != WM_CREATE)
|
if (!infoPtr && message != WM_CREATE)
|
||||||
goto HandleDefaultMessage;
|
return DefWindowProcW(hwnd, message, wParam, lParam);
|
||||||
|
|
||||||
switch(message) {
|
switch(message) {
|
||||||
case WM_PRINTCLIENT:
|
case WM_PRINTCLIENT:
|
||||||
|
@ -1588,8 +1588,8 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
|
||||||
SetCursor(LoadCursorW(0, (LPCWSTR)IDC_HAND));
|
SetCursor(LoadCursorW(0, (LPCWSTR)IDC_HAND));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/* let the default window proc handle this message */
|
|
||||||
goto HandleDefaultMessage;
|
return DefWindowProcW(hwnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
|
@ -1615,7 +1615,7 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
|
||||||
|
|
||||||
case WM_SETTEXT:
|
case WM_SETTEXT:
|
||||||
SYSLINK_SetText(infoPtr, (LPWSTR)lParam);
|
SYSLINK_SetText(infoPtr, (LPWSTR)lParam);
|
||||||
goto HandleDefaultMessage;
|
return DefWindowProcW(hwnd, message, wParam, lParam);
|
||||||
|
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
{
|
{
|
||||||
|
@ -1645,8 +1645,9 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
|
||||||
SYSKEY_SelectNextPrevLink(infoPtr, shift);
|
SYSKEY_SelectNextPrevLink(infoPtr, shift);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
return DefWindowProcW(hwnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
goto HandleDefaultMessage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_GETDLGCODE:
|
case WM_GETDLGCODE:
|
||||||
|
@ -1777,7 +1778,6 @@ static LRESULT WINAPI SysLinkWindowProc(HWND hwnd, UINT message,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
HandleDefaultMessage:
|
|
||||||
if ((message >= WM_USER) && (message < WM_APP) && !COMCTL32_IsReflectedMessage(message))
|
if ((message >= WM_USER) && (message < WM_APP) && !COMCTL32_IsReflectedMessage(message))
|
||||||
{
|
{
|
||||||
ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam );
|
ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam );
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -110,7 +111,6 @@ typedef struct
|
||||||
INT iSelected; /* the currently selected item */
|
INT iSelected; /* the currently selected item */
|
||||||
INT iHotTracked; /* the highlighted item under the mouse */
|
INT iHotTracked; /* the highlighted item under the mouse */
|
||||||
INT uFocus; /* item which has the focus */
|
INT uFocus; /* item which has the focus */
|
||||||
TAB_ITEM* items; /* pointer to an array of TAB_ITEM's */
|
|
||||||
BOOL DoRedraw; /* flag for redrawing when tab contents is changed*/
|
BOOL DoRedraw; /* flag for redrawing when tab contents is changed*/
|
||||||
BOOL needsScrolling; /* TRUE if the size of the tabs is greater than
|
BOOL needsScrolling; /* TRUE if the size of the tabs is greater than
|
||||||
* the size of the control */
|
* the size of the control */
|
||||||
|
@ -122,6 +122,8 @@ typedef struct
|
||||||
DWORD exStyle; /* Extended style used, currently:
|
DWORD exStyle; /* Extended style used, currently:
|
||||||
TCS_EX_FLATSEPARATORS, TCS_EX_REGISTERDROP */
|
TCS_EX_FLATSEPARATORS, TCS_EX_REGISTERDROP */
|
||||||
DWORD dwStyle; /* the cached window GWL_STYLE */
|
DWORD dwStyle; /* the cached window GWL_STYLE */
|
||||||
|
|
||||||
|
HDPA items; /* dynamic array of TAB_ITEM* pointers */
|
||||||
} TAB_INFO;
|
} TAB_INFO;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -141,9 +143,6 @@ typedef struct
|
||||||
#define EXTRA_ICON_PADDING 3
|
#define EXTRA_ICON_PADDING 3
|
||||||
|
|
||||||
#define TAB_GetInfoPtr(hwnd) ((TAB_INFO *)GetWindowLongPtrW(hwnd,0))
|
#define TAB_GetInfoPtr(hwnd) ((TAB_INFO *)GetWindowLongPtrW(hwnd,0))
|
||||||
/* Since items are variable sized, cannot directly access them */
|
|
||||||
#define TAB_GetItem(info,i) \
|
|
||||||
((TAB_ITEM*)((LPBYTE)info->items + (i) * TAB_ITEM_SIZE(info)))
|
|
||||||
|
|
||||||
#define GET_DEFAULT_MIN_TAB_WIDTH(infoPtr) (DEFAULT_MIN_TAB_WIDTH - (DEFAULT_PADDING_X - (infoPtr)->uHItemPadding) * 2)
|
#define GET_DEFAULT_MIN_TAB_WIDTH(infoPtr) (DEFAULT_MIN_TAB_WIDTH - (DEFAULT_PADDING_X - (infoPtr)->uHItemPadding) * 2)
|
||||||
|
|
||||||
|
@ -155,6 +154,12 @@ typedef struct
|
||||||
|
|
||||||
static const WCHAR themeClass[] = { 'T','a','b',0 };
|
static const WCHAR themeClass[] = { 'T','a','b',0 };
|
||||||
|
|
||||||
|
static inline TAB_ITEM* TAB_GetItem(const TAB_INFO *infoPtr, INT i)
|
||||||
|
{
|
||||||
|
assert(i >= 0 && i < infoPtr->uNumItem);
|
||||||
|
return DPA_GetPtr(infoPtr->items, i);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
|
@ -209,9 +214,8 @@ static void
|
||||||
TAB_DumpItemInternal(const TAB_INFO *infoPtr, UINT iItem)
|
TAB_DumpItemInternal(const TAB_INFO *infoPtr, UINT iItem)
|
||||||
{
|
{
|
||||||
if (TRACE_ON(tab)) {
|
if (TRACE_ON(tab)) {
|
||||||
TAB_ITEM *ti;
|
TAB_ITEM *ti = TAB_GetItem(infoPtr, iItem);
|
||||||
|
|
||||||
ti = TAB_GetItem(infoPtr, iItem);
|
|
||||||
TRACE("tab %d, dwState=0x%08x, pszText=%s, iImage=%d\n",
|
TRACE("tab %d, dwState=0x%08x, pszText=%s, iImage=%d\n",
|
||||||
iItem, ti->dwState, debugstr_w(ti->pszText), ti->iImage);
|
iItem, ti->dwState, debugstr_w(ti->pszText), ti->iImage);
|
||||||
TRACE("tab %d, rect.left=%d, rect.top(row)=%d\n",
|
TRACE("tab %d, rect.left=%d, rect.top(row)=%d\n",
|
||||||
|
@ -702,11 +706,10 @@ TAB_LButtonUp (const TAB_INFO *infoPtr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline LRESULT
|
static inline void
|
||||||
TAB_RButtonDown (const TAB_INFO *infoPtr)
|
TAB_RButtonUp (const TAB_INFO *infoPtr)
|
||||||
{
|
{
|
||||||
TAB_SendSimpleNotify(infoPtr, NM_RCLICK);
|
TAB_SendSimpleNotify(infoPtr, NM_RCLICK);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -1766,6 +1769,7 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
|
||||||
{
|
{
|
||||||
/* this could be considered broken on 64 bit, but that's how it works -
|
/* this could be considered broken on 64 bit, but that's how it works -
|
||||||
only first 4 bytes are copied */
|
only first 4 bytes are copied */
|
||||||
|
dis.itemData = 0;
|
||||||
memcpy(&dis.itemData, (ULONG_PTR*)TAB_GetItem(infoPtr, iItem)->extra, 4);
|
memcpy(&dis.itemData, (ULONG_PTR*)TAB_GetItem(infoPtr, iItem)->extra, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2113,9 +2117,10 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC hdc, INT iItem)
|
||||||
partIndex += 4;
|
partIndex += 4;
|
||||||
/* The part also differs on the position of a tab on a line.
|
/* The part also differs on the position of a tab on a line.
|
||||||
* "Visually" determining the position works well enough. */
|
* "Visually" determining the position works well enough. */
|
||||||
|
GetClientRect(infoPtr->hwnd, &r1);
|
||||||
if(selectedRect.left == 0)
|
if(selectedRect.left == 0)
|
||||||
partIndex += 1;
|
partIndex += 1;
|
||||||
if(selectedRect.right == clRight)
|
if(selectedRect.right == r1.right)
|
||||||
partIndex += 2;
|
partIndex += 2;
|
||||||
|
|
||||||
if (iItem == infoPtr->iSelected)
|
if (iItem == infoPtr->iSelected)
|
||||||
|
@ -2436,6 +2441,9 @@ static void TAB_EnsureSelectionVisible(
|
||||||
INT iSelected = infoPtr->iSelected;
|
INT iSelected = infoPtr->iSelected;
|
||||||
INT iOrigLeftmostVisible = infoPtr->leftmostVisible;
|
INT iOrigLeftmostVisible = infoPtr->leftmostVisible;
|
||||||
|
|
||||||
|
if (iSelected < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/* set the items row to the bottommost row or topmost row depending on
|
/* set the items row to the bottommost row or topmost row depending on
|
||||||
* style */
|
* style */
|
||||||
if ((infoPtr->uNumRows > 1) && !(infoPtr->dwStyle & TCS_BUTTONS))
|
if ((infoPtr->uNumRows > 1) && !(infoPtr->dwStyle & TCS_BUTTONS))
|
||||||
|
@ -2640,42 +2648,21 @@ TAB_InsertItemT (TAB_INFO *infoPtr, INT iItem, const TCITEMW *pti, BOOL bUnicode
|
||||||
|
|
||||||
TAB_DumpItemExternalT(pti, iItem, bUnicode);
|
TAB_DumpItemExternalT(pti, iItem, bUnicode);
|
||||||
|
|
||||||
|
if (!(item = Alloc(TAB_ITEM_SIZE(infoPtr)))) return FALSE;
|
||||||
if (infoPtr->uNumItem == 0) {
|
if (DPA_InsertPtr(infoPtr->items, iItem, item) == -1)
|
||||||
infoPtr->items = Alloc (TAB_ITEM_SIZE(infoPtr));
|
{
|
||||||
infoPtr->uNumItem++;
|
Free(item);
|
||||||
infoPtr->iSelected = 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
LPBYTE oldItems = (LPBYTE)infoPtr->items;
|
|
||||||
|
|
||||||
infoPtr->uNumItem++;
|
if (infoPtr->uNumItem == 0)
|
||||||
infoPtr->items = Alloc (TAB_ITEM_SIZE(infoPtr) * infoPtr->uNumItem);
|
infoPtr->iSelected = 0;
|
||||||
|
else if (iItem <= infoPtr->iSelected)
|
||||||
/* pre insert copy */
|
|
||||||
if (iItem > 0) {
|
|
||||||
memcpy (infoPtr->items, oldItems,
|
|
||||||
iItem * TAB_ITEM_SIZE(infoPtr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* post insert copy */
|
|
||||||
if (iItem < infoPtr->uNumItem - 1) {
|
|
||||||
memcpy (TAB_GetItem(infoPtr, iItem + 1),
|
|
||||||
oldItems + iItem * TAB_ITEM_SIZE(infoPtr),
|
|
||||||
(infoPtr->uNumItem - iItem - 1) * TAB_ITEM_SIZE(infoPtr));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iItem <= infoPtr->iSelected)
|
|
||||||
infoPtr->iSelected++;
|
infoPtr->iSelected++;
|
||||||
|
|
||||||
Free (oldItems);
|
infoPtr->uNumItem++;
|
||||||
}
|
|
||||||
|
|
||||||
item = TAB_GetItem(infoPtr, iItem);
|
|
||||||
|
|
||||||
item->pszText = NULL;
|
item->pszText = NULL;
|
||||||
|
|
||||||
if (pti->mask & TCIF_TEXT)
|
if (pti->mask & TCIF_TEXT)
|
||||||
{
|
{
|
||||||
if (bUnicode)
|
if (bUnicode)
|
||||||
|
@ -2885,64 +2872,49 @@ TAB_GetItemT (TAB_INFO *infoPtr, INT iItem, LPTCITEMW tabItem, BOOL bUnicode)
|
||||||
|
|
||||||
static LRESULT TAB_DeleteItem (TAB_INFO *infoPtr, INT iItem)
|
static LRESULT TAB_DeleteItem (TAB_INFO *infoPtr, INT iItem)
|
||||||
{
|
{
|
||||||
BOOL bResult = FALSE;
|
TAB_ITEM *item;
|
||||||
|
|
||||||
TRACE("(%p, %d)\n", infoPtr, iItem);
|
TRACE("(%p, %d)\n", infoPtr, iItem);
|
||||||
|
|
||||||
if ((iItem >= 0) && (iItem < infoPtr->uNumItem))
|
if (iItem < 0 || iItem >= infoPtr->uNumItem) return FALSE;
|
||||||
|
|
||||||
|
item = TAB_GetItem(infoPtr, iItem);
|
||||||
|
Free(item->pszText);
|
||||||
|
Free(item);
|
||||||
|
infoPtr->uNumItem--;
|
||||||
|
DPA_DeletePtr(infoPtr->items, iItem);
|
||||||
|
|
||||||
|
TAB_InvalidateTabArea(infoPtr);
|
||||||
|
|
||||||
|
if (infoPtr->uNumItem == 0)
|
||||||
{
|
{
|
||||||
TAB_ITEM *item = TAB_GetItem(infoPtr, iItem);
|
if (infoPtr->iHotTracked >= 0)
|
||||||
LPBYTE oldItems = (LPBYTE)infoPtr->items;
|
|
||||||
|
|
||||||
TAB_InvalidateTabArea(infoPtr);
|
|
||||||
Free(item->pszText);
|
|
||||||
infoPtr->uNumItem--;
|
|
||||||
|
|
||||||
if (!infoPtr->uNumItem)
|
|
||||||
{
|
{
|
||||||
infoPtr->items = NULL;
|
KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);
|
||||||
if (infoPtr->iHotTracked >= 0)
|
infoPtr->iHotTracked = -1;
|
||||||
{
|
|
||||||
KillTimer(infoPtr->hwnd, TAB_HOTTRACK_TIMER);
|
|
||||||
infoPtr->iHotTracked = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
infoPtr->items = Alloc(TAB_ITEM_SIZE(infoPtr) * infoPtr->uNumItem);
|
|
||||||
|
|
||||||
if (iItem > 0)
|
infoPtr->iSelected = -1;
|
||||||
memcpy(infoPtr->items, oldItems, iItem * TAB_ITEM_SIZE(infoPtr));
|
}
|
||||||
|
else
|
||||||
if (iItem < infoPtr->uNumItem)
|
{
|
||||||
memcpy(TAB_GetItem(infoPtr, iItem),
|
if (iItem <= infoPtr->iHotTracked)
|
||||||
oldItems + (iItem + 1) * TAB_ITEM_SIZE(infoPtr),
|
{
|
||||||
(infoPtr->uNumItem - iItem) * TAB_ITEM_SIZE(infoPtr));
|
/* When tabs move left/up, the hot track item may change */
|
||||||
|
FIXME("Recalc hot track\n");
|
||||||
if (iItem <= infoPtr->iHotTracked)
|
}
|
||||||
{
|
|
||||||
/* When tabs move left/up, the hot track item may change */
|
|
||||||
FIXME("Recalc hot track\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Free(oldItems);
|
|
||||||
|
|
||||||
/* Readjust the selected index */
|
|
||||||
if (iItem == infoPtr->iSelected)
|
|
||||||
infoPtr->iSelected = -1;
|
|
||||||
else if (iItem < infoPtr->iSelected)
|
|
||||||
infoPtr->iSelected--;
|
|
||||||
|
|
||||||
if (infoPtr->uNumItem == 0)
|
|
||||||
infoPtr->iSelected = -1;
|
|
||||||
|
|
||||||
/* Reposition and repaint tabs */
|
|
||||||
TAB_SetItemBounds(infoPtr);
|
|
||||||
|
|
||||||
bResult = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bResult;
|
/* adjust the selected index */
|
||||||
|
if (iItem == infoPtr->iSelected)
|
||||||
|
infoPtr->iSelected = -1;
|
||||||
|
else if (iItem < infoPtr->iSelected)
|
||||||
|
infoPtr->iSelected--;
|
||||||
|
|
||||||
|
/* reposition and repaint tabs */
|
||||||
|
TAB_SetItemBounds(infoPtr);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline LRESULT TAB_DeleteAllItems (TAB_INFO *infoPtr)
|
static inline LRESULT TAB_DeleteAllItems (TAB_INFO *infoPtr)
|
||||||
|
@ -3063,7 +3035,7 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam)
|
||||||
infoPtr->uHItemPadding_s = 6;
|
infoPtr->uHItemPadding_s = 6;
|
||||||
infoPtr->uVItemPadding_s = 3;
|
infoPtr->uVItemPadding_s = 3;
|
||||||
infoPtr->hFont = 0;
|
infoPtr->hFont = 0;
|
||||||
infoPtr->items = 0;
|
infoPtr->items = DPA_Create(8);
|
||||||
infoPtr->hcurArrow = LoadCursorW (0, (LPWSTR)IDC_ARROW);
|
infoPtr->hcurArrow = LoadCursorW (0, (LPWSTR)IDC_ARROW);
|
||||||
infoPtr->iSelected = -1;
|
infoPtr->iSelected = -1;
|
||||||
infoPtr->iHotTracked = -1;
|
infoPtr->iHotTracked = -1;
|
||||||
|
@ -3147,16 +3119,22 @@ static LRESULT TAB_Create (HWND hwnd, LPARAM lParam)
|
||||||
static LRESULT
|
static LRESULT
|
||||||
TAB_Destroy (TAB_INFO *infoPtr)
|
TAB_Destroy (TAB_INFO *infoPtr)
|
||||||
{
|
{
|
||||||
UINT iItem;
|
INT iItem;
|
||||||
|
|
||||||
SetWindowLongPtrW(infoPtr->hwnd, 0, 0);
|
SetWindowLongPtrW(infoPtr->hwnd, 0, 0);
|
||||||
|
|
||||||
if (infoPtr->items) {
|
for (iItem = infoPtr->uNumItem - 1; iItem >= 0; iItem--)
|
||||||
for (iItem = 0; iItem < infoPtr->uNumItem; iItem++) {
|
{
|
||||||
Free (TAB_GetItem(infoPtr, iItem)->pszText);
|
TAB_ITEM *tab = TAB_GetItem(infoPtr, iItem);
|
||||||
}
|
|
||||||
Free (infoPtr->items);
|
DPA_DeletePtr(infoPtr->items, iItem);
|
||||||
|
infoPtr->uNumItem--;
|
||||||
|
|
||||||
|
Free(tab->pszText);
|
||||||
|
Free(tab);
|
||||||
}
|
}
|
||||||
|
DPA_Destroy(infoPtr->items);
|
||||||
|
infoPtr->items = NULL;
|
||||||
|
|
||||||
if (infoPtr->hwndToolTip)
|
if (infoPtr->hwndToolTip)
|
||||||
DestroyWindow (infoPtr->hwndToolTip);
|
DestroyWindow (infoPtr->hwndToolTip);
|
||||||
|
@ -3450,8 +3428,9 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_NOTIFY:
|
case WM_NOTIFY:
|
||||||
return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
|
return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, wParam, lParam);
|
||||||
|
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONUP:
|
||||||
return TAB_RButtonDown (infoPtr);
|
TAB_RButtonUp (infoPtr);
|
||||||
|
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
|
||||||
|
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
return TAB_MouseMove (infoPtr, wParam, lParam);
|
return TAB_MouseMove (infoPtr, wParam, lParam);
|
||||||
|
|
|
@ -246,18 +246,26 @@ static BOOL BUTTON_Paint(HTHEME theme, HWND hwnd, HDC hParamDC)
|
||||||
DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
|
DWORD dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
|
||||||
DWORD dwStyleEx = GetWindowLongW(hwnd, GWL_EXSTYLE);
|
DWORD dwStyleEx = GetWindowLongW(hwnd, GWL_EXSTYLE);
|
||||||
UINT dtFlags = get_drawtext_flags(dwStyle, dwStyleEx);
|
UINT dtFlags = get_drawtext_flags(dwStyle, dwStyleEx);
|
||||||
ButtonState drawState = IsWindowEnabled(hwnd) ? STATE_NORMAL : STATE_DISABLED;
|
int state = (int)SendMessageW(hwnd, BM_GETSTATE, 0, 0);
|
||||||
|
ButtonState drawState;
|
||||||
pfThemedPaint paint = btnThemedPaintFunc[ dwStyle & BUTTON_TYPE ];
|
pfThemedPaint paint = btnThemedPaintFunc[ dwStyle & BUTTON_TYPE ];
|
||||||
|
|
||||||
if (paint)
|
if(!paint)
|
||||||
{
|
return FALSE;
|
||||||
hDC = hParamDC ? hParamDC : BeginPaint(hwnd, &ps);
|
|
||||||
paint(theme, hwnd, hDC, drawState, dtFlags);
|
|
||||||
if (!hParamDC) EndPaint(hwnd, &ps);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE; /* Delegate drawing to the non-themed code. */
|
if(IsWindowEnabled(hwnd))
|
||||||
|
{
|
||||||
|
if(state & BST_PUSHED) drawState = STATE_PRESSED;
|
||||||
|
else if(state & BST_HOT) drawState = STATE_HOT;
|
||||||
|
else if(state & BST_FOCUS) drawState = STATE_DEFAULTED;
|
||||||
|
else drawState = STATE_NORMAL;
|
||||||
|
}
|
||||||
|
else drawState = STATE_DISABLED;
|
||||||
|
|
||||||
|
hDC = hParamDC ? hParamDC : BeginPaint(hwnd, &ps);
|
||||||
|
paint(theme, hwnd, hDC, drawState, dtFlags);
|
||||||
|
if (!hParamDC) EndPaint(hwnd, &ps);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
@ -309,6 +317,37 @@ LRESULT CALLBACK THEMING_ButtonSubclassProc(HWND hwnd, UINT msg,
|
||||||
RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
|
RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
|
||||||
return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
|
return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
|
||||||
|
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
{
|
||||||
|
TRACKMOUSEEVENT mouse_event;
|
||||||
|
mouse_event.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||||
|
mouse_event.dwFlags = TME_QUERY;
|
||||||
|
if(!TrackMouseEvent(&mouse_event) || !(mouse_event.dwFlags&(TME_HOVER|TME_LEAVE)))
|
||||||
|
{
|
||||||
|
mouse_event.dwFlags = TME_HOVER|TME_LEAVE;
|
||||||
|
mouse_event.hwndTrack = hwnd;
|
||||||
|
mouse_event.dwHoverTime = 1;
|
||||||
|
TrackMouseEvent(&mouse_event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_MOUSEHOVER:
|
||||||
|
{
|
||||||
|
int state = (int)SendMessageW(hwnd, BM_GETSTATE, 0, 0);
|
||||||
|
SetWindowLongW(hwnd, 0, state|BST_HOT);
|
||||||
|
InvalidateRect(hwnd, NULL, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WM_MOUSELEAVE:
|
||||||
|
{
|
||||||
|
int state = (int)SendMessageW(hwnd, BM_GETSTATE, 0, 0);
|
||||||
|
SetWindowLongW(hwnd, 0, state&(~BST_HOT));
|
||||||
|
InvalidateRect(hwnd, NULL, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Call old proc */
|
/* Call old proc */
|
||||||
return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
|
return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
|
||||||
|
|
|
@ -54,7 +54,9 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
CloseThemeData ( theme );
|
CloseThemeData ( theme );
|
||||||
return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
|
SetWindowTheme( hWnd, NULL, NULL );
|
||||||
|
OpenThemeData( hWnd, NULL );
|
||||||
|
return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam);
|
||||||
|
|
||||||
case WM_THEMECHANGED:
|
case WM_THEMECHANGED:
|
||||||
CloseThemeData ( theme );
|
CloseThemeData ( theme );
|
||||||
|
|
|
@ -35,15 +35,15 @@ typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM,
|
||||||
ULONG_PTR);
|
ULONG_PTR);
|
||||||
|
|
||||||
extern LRESULT CALLBACK THEMING_ButtonSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
extern LRESULT CALLBACK THEMING_ButtonSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
||||||
ULONG_PTR);
|
ULONG_PTR) DECLSPEC_HIDDEN;
|
||||||
extern LRESULT CALLBACK THEMING_ComboSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
extern LRESULT CALLBACK THEMING_ComboSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
||||||
ULONG_PTR);
|
ULONG_PTR) DECLSPEC_HIDDEN;
|
||||||
extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
||||||
ULONG_PTR);
|
ULONG_PTR) DECLSPEC_HIDDEN;
|
||||||
extern LRESULT CALLBACK THEMING_EditSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
extern LRESULT CALLBACK THEMING_EditSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
||||||
ULONG_PTR);
|
ULONG_PTR) DECLSPEC_HIDDEN;
|
||||||
extern LRESULT CALLBACK THEMING_ListBoxSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
extern LRESULT CALLBACK THEMING_ListBoxSubclassProc (HWND, UINT, WPARAM, LPARAM,
|
||||||
ULONG_PTR);
|
ULONG_PTR) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
static const WCHAR dialogClass[] = {'#','3','2','7','7','0',0};
|
static const WCHAR dialogClass[] = {'#','3','2','7','7','0',0};
|
||||||
static const WCHAR comboLboxClass[] = {'C','o','m','b','o','L','b','o','x',0};
|
static const WCHAR comboLboxClass[] = {'C','o','m','b','o','L','b','o','x',0};
|
||||||
|
|
|
@ -574,7 +574,7 @@ TOOLBAR_DrawString (const TOOLBAR_INFO *infoPtr, RECT *rcText, LPCWSTR lpText,
|
||||||
UINT state = tbcd->nmcd.uItemState;
|
UINT state = tbcd->nmcd.uItemState;
|
||||||
|
|
||||||
/* draw text */
|
/* draw text */
|
||||||
if (lpText) {
|
if (lpText && infoPtr->nMaxTextRows > 0) {
|
||||||
TRACE("string=%s rect=(%s)\n", debugstr_w(lpText),
|
TRACE("string=%s rect=(%s)\n", debugstr_w(lpText),
|
||||||
wine_dbgstr_rect(rcText));
|
wine_dbgstr_rect(rcText));
|
||||||
|
|
||||||
|
@ -2305,7 +2305,7 @@ static LRESULT TOOLBAR_Cust_AvailDragListNotification(const CUSTDLG_INFO *custIn
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern UINT uDragListMessage;
|
extern UINT uDragListMessage DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* TOOLBAR_CustomizeDialogProc
|
* TOOLBAR_CustomizeDialogProc
|
||||||
|
|
|
@ -1979,37 +1979,13 @@ TOOLTIPS_NCHitTest (const TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
static LRESULT
|
static LRESULT
|
||||||
TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
TOOLTIPS_NotifyFormat (TOOLTIPS_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
TTTOOL_INFO *toolPtr = infoPtr->tools;
|
FIXME ("hwnd=%p wParam=%lx lParam=%lx\n", infoPtr->hwndSelf, wParam, lParam);
|
||||||
LRESULT nResult;
|
|
||||||
|
|
||||||
TRACE("infoPtr=%p wParam=%lx lParam=%p\n", infoPtr, wParam, (PVOID)lParam);
|
|
||||||
|
|
||||||
if (lParam == NF_QUERY) {
|
|
||||||
if (toolPtr->bNotifyUnicode) {
|
|
||||||
return NFR_UNICODE;
|
|
||||||
} else {
|
|
||||||
return NFR_ANSI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (lParam == NF_REQUERY) {
|
|
||||||
nResult = SendMessageW (toolPtr->hwnd, WM_NOTIFYFORMAT,
|
|
||||||
(WPARAM)infoPtr->hwndSelf, (LPARAM)NF_QUERY);
|
|
||||||
if (nResult == NFR_ANSI) {
|
|
||||||
toolPtr->bNotifyUnicode = FALSE;
|
|
||||||
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_ANSI\n");
|
|
||||||
} else if (nResult == NFR_UNICODE) {
|
|
||||||
toolPtr->bNotifyUnicode = TRUE;
|
|
||||||
TRACE(" -- WM_NOTIFYFORMAT returns: NFR_UNICODE\n");
|
|
||||||
} else {
|
|
||||||
TRACE (" -- WM_NOTIFYFORMAT returns: error!\n");
|
|
||||||
}
|
|
||||||
return nResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static LRESULT
|
static LRESULT
|
||||||
TOOLTIPS_Paint (const TOOLTIPS_INFO *infoPtr, HDC hDC)
|
TOOLTIPS_Paint (const TOOLTIPS_INFO *infoPtr, HDC hDC)
|
||||||
{
|
{
|
||||||
|
@ -2076,7 +2052,7 @@ TOOLTIPS_OnWMGetText (const TOOLTIPS_INFO *infoPtr, WPARAM size, LPWSTR pszText)
|
||||||
{
|
{
|
||||||
LRESULT res;
|
LRESULT res;
|
||||||
|
|
||||||
if(!infoPtr->szTipText || !size)
|
if(!size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
res = min(strlenW(infoPtr->szTipText)+1, size);
|
res = min(strlenW(infoPtr->szTipText)+1, size);
|
||||||
|
|
Loading…
Reference in a new issue