pkg://wine-981025-1.src.rpm:2548475/Wine-981025.tar.gz
info downloads
wine-981025/ 40755 771 771 0 6614657101 12362 5 ustar julliard julliard wine-981025/dlls/ 40755 771 771 0 6614657075 13332 5 ustar julliard julliard wine-981025/dlls/.cvsignore 100644 771 771 11 6605734113 15344 0 ustar julliard julliard Makefile
wine-981025/dlls/Makefile.in 100644 771 771 730 6610163100 15425 0 ustar julliard julliard SUBDIRS = \
comctl32 \
imagehlp \
msacm \
msacm32 \
psapi \
shell32 \
winaspi \
wnaspi32
all: $(SUBDIRS)
$(SUBDIRS): dummy
@cd $@; $(MAKE)
depend:
for i in $(SUBDIRS); do (cd $$i && $(MAKE) depend) || exit 1; done
install:
for i in $(SUBDIRS); do (cd $$i && $(MAKE) install) || exit 1; done
uninstall:
for i in $(SUBDIRS); do (cd $$i && $(MAKE) uninstall) || exit 1; done
clean:
for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean) || exit 1; done
dummy:
wine-981025/dlls/comctl32/ 40755 771 771 0 6614657075 14760 5 ustar julliard julliard wine-981025/dlls/comctl32/.cvsignore 100644 771 771 11 6605734127 16777 0 ustar julliard julliard Makefile
wine-981025/dlls/comctl32/Makefile.in 100644 771 771 724 6610127773 17076 0 ustar julliard julliard DEFS = @DLLFLAGS@ -D__WINE__
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = comctl32
C_SRCS = \
animate.c \
comboex.c \
comctl32undoc.c \
commctrl.c \
header.c \
hotkey.c \
imagelist.c \
ipaddress.c \
listview.c \
nativefont.c \
pager.c \
progress.c \
rebar.c \
status.c \
tab.c \
toolbar.c \
tooltips.c \
trackbar.c \
treeview.c \
updown.c
all: $(MODULE).o
@MAKE_RULES@
### Dependencies:
wine-981025/dlls/comctl32/animate.c 100644 771 771 15056 6614330267 16655 0 ustar julliard julliard /*
* Animation control
*
* Copyright 1998 Eric Kohl
*
* NOTES
* This is just a dummy control. An author is needed! Any volunteers?
* I will only improve this control once in a while.
* Eric <ekohl@abo.rhein-zeitung.de>
*
* TODO:
* - All messages.
* - All notifications.
*/
#include "windows.h"
#include "winnt.h"
#include "winbase.h"
#include "commctrl.h"
#include "animate.h"
#include "win.h"
#include "debug.h"
#define ANIMATE_GetInfoPtr(wndPtr) ((ANIMATE_INFO *)wndPtr->wExtra[0])
static BOOL32
ANIMATE_LoadRes32A (ANIMATE_INFO *infoPtr, HINSTANCE32 hInst, LPSTR lpName)
{
HRSRC32 hrsrc;
HGLOBAL32 handle;
hrsrc = FindResource32A (hInst, lpName, "AVI");
if (!hrsrc)
return FALSE;
handle = LoadResource32 (hInst, hrsrc);
if (!handle)
return FALSE;
infoPtr->lpAvi = LockResource32 (handle);
if (!infoPtr->lpAvi)
return FALSE;
return TRUE;
}
static BOOL32
ANIMATE_LoadFile32A (ANIMATE_INFO *infoPtr, LPSTR lpName)
{
HANDLE32 handle;
infoPtr->hFile =
CreateFile32A (lpName, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (!infoPtr->hFile)
return FALSE;
handle =
CreateFileMapping32A (infoPtr->hFile, NULL, PAGE_READONLY | SEC_COMMIT,
0, 0, NULL);
if (!handle) {
CloseHandle (infoPtr->hFile);
infoPtr->hFile = 0;
return FALSE;
}
infoPtr->lpAvi = MapViewOfFile (handle, FILE_MAP_READ, 0, 0, 0);
if (!infoPtr->lpAvi) {
CloseHandle (infoPtr->hFile);
infoPtr->hFile = 0;
return FALSE;
}
return TRUE;
}
static VOID
ANIMATE_Free (ANIMATE_INFO *infoPtr)
{
if (infoPtr->hFile) {
UnmapViewOfFile (infoPtr->lpAvi);
CloseHandle (infoPtr->hFile);
infoPtr->lpAvi = NULL;
}
else {
GlobalFree32 (infoPtr->lpAvi);
infoPtr->lpAvi = NULL;
}
}
static VOID
ANIMATE_GetAviInfo (infoPtr)
{
}
static LRESULT
ANIMATE_Open32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr);
HINSTANCE32 hInstance = (HINSTANCE32)wParam;
ANIMATE_Free (infoPtr);
if (!lParam) {
TRACE (animate, "closing avi!\n");
return TRUE;
}
if (HIWORD(lParam)) {
FIXME (animate, "(\"%s\") empty stub!\n", (LPSTR)lParam);
if (ANIMATE_LoadRes32A (infoPtr, hInstance, (LPSTR)lParam)) {
FIXME (animate, "AVI resource found!\n");
}
else {
FIXME (animate, "No AVI resource found!\n");
if (ANIMATE_LoadFile32A (infoPtr, (LPSTR)lParam)) {
FIXME (animate, "AVI file found!\n");
}
else {
FIXME (animate, "No AVI file found!\n");
return FALSE;
}
}
}
else {
FIXME (animate, "(%u) empty stub!\n", (WORD)LOWORD(lParam));
if (ANIMATE_LoadRes32A (infoPtr, hInstance,
MAKEINTRESOURCE32A((INT32)lParam))) {
FIXME (animate, "AVI resource found!\n");
}
else {
FIXME (animate, "No AVI resource found!\n");
return FALSE;
}
}
ANIMATE_GetAviInfo (infoPtr);
return TRUE;
}
// << ANIMATE_Open32W >>
static LRESULT
ANIMATE_Play (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr);
INT32 nFrom = (INT32)LOWORD(lParam);
INT32 nTo = (INT32)HIWORD(lParam);
INT32 nRepeat = (INT32)wParam;
#if 0
/* nothing opened */
if (...)
return FALSE;
#endif
if (nRepeat == -1) {
FIXME (animate, "(loop from=%d to=%d) empty stub!\n",
nFrom, nTo);
}
else {
FIXME (animate, "(repeat=%d from=%d to=%d) empty stub!\n",
nRepeat, nFrom, nTo);
}
return TRUE;
}
static LRESULT
ANIMATE_Stop (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr);
#if 0
/* nothing opened */
if (...)
return FALSE;
#endif
return TRUE;
}
static LRESULT
ANIMATE_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
ANIMATE_INFO *infoPtr;
/* allocate memory for info structure */
infoPtr = (ANIMATE_INFO *)COMCTL32_Alloc (sizeof(ANIMATE_INFO));
wndPtr->wExtra[0] = (DWORD)infoPtr;
if (infoPtr == NULL) {
ERR (animate, "could not allocate info memory!\n");
return 0;
}
if ((ANIMATE_INFO*)wndPtr->wExtra[0] != infoPtr) {
ERR (animate, "pointer assignment error!\n");
return 0;
}
/* set default settings */
return 0;
}
static LRESULT
ANIMATE_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr);
/* free avi data */
ANIMATE_Free (infoPtr);
/* free animate info data */
COMCTL32_Free (infoPtr);
return 0;
}
#if 0
static LRESULT
ANIMATE_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(wndPtr);
/*
HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
RECT32 rect;
GetClientRect32 (wndPtr->hwndSelf, &rect);
FillRect32 ((HDC32)wParam, &rect, hBrush);
DeleteObject32 (hBrush);
*/
return TRUE;
}
#endif
LRESULT WINAPI
ANIMATE_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
switch (uMsg)
{
case ACM_OPEN32A:
return ANIMATE_Open32A (wndPtr, wParam, lParam);
// case ACM_OPEN32W:
// return ANIMATE_Open32W (wndPtr, wParam, lParam);
case ACM_PLAY:
return ANIMATE_Play (wndPtr, wParam, lParam);
case ACM_STOP:
return ANIMATE_Stop (wndPtr, wParam, lParam);
case WM_CREATE:
return ANIMATE_Create (wndPtr, wParam, lParam);
case WM_DESTROY:
return ANIMATE_Destroy (wndPtr, wParam, lParam);
// case WM_ERASEBKGND:
// return ANIMATE_EraseBackground (wndPtr, wParam, lParam);
// case WM_NCCREATE:
// case WM_NCHITTEST:
// case WM_PAINT:
// case WM_SIZE:
// case WM_STYLECHANGED:
// case WM_TIMER:
default:
if (uMsg >= WM_USER)
ERR (animate, "unknown msg %04x wp=%08x lp=%08lx\n",
uMsg, wParam, lParam);
return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
}
return 0;
}
VOID
ANIMATE_Register (VOID)
{
WNDCLASS32A wndClass;
if (GlobalFindAtom32A (ANIMATE_CLASS32A)) return;
ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
wndClass.lpfnWndProc = (WNDPROC32)ANIMATE_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(ANIMATE_INFO *);
wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
wndClass.hbrBackground = (HBRUSH32)(COLOR_BTNFACE + 1);
wndClass.lpszClassName = ANIMATE_CLASS32A;
RegisterClass32A (&wndClass);
}
VOID
ANIMATE_Unregister (VOID)
{
if (GlobalFindAtom32A (ANIMATE_CLASS32A))
UnregisterClass32A (ANIMATE_CLASS32A, (HINSTANCE32)NULL);
}
wine-981025/dlls/comctl32/comboex.c 100644 771 771 14260 6614330267 16667 0 ustar julliard julliard /*
* ComboBoxEx control
*
* Copyright 1998 Eric Kohl
*
* NOTES
* This is just a dummy control. An author is needed! Any volunteers?
* I will only improve this control once in a while.
* Eric <ekohl@abo.rhein-zeitung.de>
*
* TODO:
* - All messages.
* - All notifications.
*
* FIXME:
* - should include "combo.h"
*/
#include "windows.h"
#include "commctrl.h"
#include "comboex.h"
#include "win.h"
#include "debug.h"
#define ID_CB_EDIT 1001
#define COMBOEX_GetInfoPtr(wndPtr) ((COMBOEX_INFO *)wndPtr->wExtra[0])
// << COMBOEX_DeleteItem >>
__inline__ static LRESULT
COMBOEX_GetComboControl (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
TRACE (comboex, "\n");
return (LRESULT)infoPtr->hwndCombo;
}
__inline__ static LRESULT
COMBOEX_GetEditControl (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
if ((wndPtr->dwStyle & CBS_DROPDOWNLIST) != CBS_DROPDOWN)
return 0;
FIXME (comboex, "-- 0x%x\n", GetDlgItem32 (infoPtr->hwndCombo, ID_CB_EDIT));
return (LRESULT)GetDlgItem32 (infoPtr->hwndCombo, ID_CB_EDIT);
}
__inline__ static LRESULT
COMBOEX_GetExtendedStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
return (LRESULT)infoPtr->dwExtStyle;
}
__inline__ static LRESULT
COMBOEX_GetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
TRACE (comboex, "(0x%08x 0x%08lx)\n", wParam, lParam);
return (LRESULT)infoPtr->himl;
}
static LRESULT
COMBOEX_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
FIXME (comboex, "(0x%08x 0x%08lx)\n", wParam, lParam);
return -1;
}
static LRESULT
COMBOEX_SetExtendedStyle (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
DWORD dwTemp;
TRACE (comboex, "(0x%08x 0x%08lx)\n", wParam, lParam);
dwTemp = infoPtr->dwExtStyle;
if ((DWORD)wParam) {
infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~(DWORD)wParam) | (DWORD)lParam;
}
else
infoPtr->dwExtStyle = (DWORD)lParam;
/* FIXME: repaint?? */
return (LRESULT)dwTemp;
}
__inline__ static LRESULT
COMBOEX_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
HIMAGELIST himlTemp;
TRACE (comboex, "(0x%08x 0x%08lx)\n", wParam, lParam);
himlTemp = infoPtr->himl;
infoPtr->himl = (HIMAGELIST)lParam;
return (LRESULT)himlTemp;
}
static LRESULT
COMBOEX_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr;
DWORD dwComboStyle;
/* allocate memory for info structure */
infoPtr = (COMBOEX_INFO *)COMCTL32_Alloc (sizeof(COMBOEX_INFO));
wndPtr->wExtra[0] = (DWORD)infoPtr;
if (infoPtr == NULL) {
ERR (listview, "could not allocate info memory!\n");
return 0;
}
if ((COMBOEX_INFO*)wndPtr->wExtra[0] != infoPtr) {
ERR (listview, "pointer assignment error!\n");
return 0;
}
/* initialize info structure */
/* create combo box */
dwComboStyle =
wndPtr->dwStyle & (CBS_SIMPLE|CBS_DROPDOWN|CBS_DROPDOWNLIST|WS_CHILD);
infoPtr->hwndCombo =
CreateWindow32A ("ComboBox", "",
WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | dwComboStyle,
0, 0, 0, 0, wndPtr->hwndSelf, (HMENU32)1,
wndPtr->hInstance, NULL);
return 0;
}
static LRESULT
COMBOEX_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
if (infoPtr->hwndCombo)
DestroyWindow32 (infoPtr->hwndCombo);
/* free comboex info data */
COMCTL32_Free (infoPtr);
return 0;
}
static LRESULT
COMBOEX_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr(wndPtr);
RECT32 rect;
GetClientRect32 (wndPtr->hwndSelf, &rect);
MoveWindow32 (infoPtr->hwndCombo, 0, 0, rect.right -rect.left,
rect.bottom - rect.top, TRUE);
return 0;
}
LRESULT WINAPI
COMBOEX_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
switch (uMsg)
{
// case CBEM_DELETEITEM:
case CBEM_GETCOMBOCONTROL:
return COMBOEX_GetComboControl (wndPtr, wParam, lParam);
case CBEM_GETEDITCONTROL:
return COMBOEX_GetEditControl (wndPtr, wParam, lParam);
case CBEM_GETEXTENDEDSTYLE:
return COMBOEX_GetExtendedStyle (wndPtr, wParam, lParam);
case CBEM_GETIMAGELIST:
return COMBOEX_GetImageList (wndPtr, wParam, lParam);
// case CBEM_GETITEM32A:
// case CBEM_GETITEM32W:
// case CBEM_GETUNICODEFORMAT:
// case CBEM_HASEDITCHANGED:
case CBEM_INSERTITEM32A:
return COMBOEX_InsertItem32A (wndPtr, wParam, lParam);
// case CBEM_INSERTITEM32W:
case CBEM_SETEXTENDEDSTYLE:
return COMBOEX_SetExtendedStyle (wndPtr, wParam, lParam);
case CBEM_SETIMAGELIST:
return COMBOEX_SetImageList (wndPtr, wParam, lParam);
// case CBEM_SETITEM32A:
// case CBEM_SETITEM32W:
// case CBEM_SETUNICODEFORMAT:
case WM_CREATE:
return COMBOEX_Create (wndPtr, wParam, lParam);
case WM_DESTROY:
return COMBOEX_Destroy (wndPtr, wParam, lParam);
case WM_SIZE:
return COMBOEX_Size (wndPtr, wParam, lParam);
default:
if (uMsg >= WM_USER)
ERR (comboex, "unknown msg %04x wp=%08x lp=%08lx\n",
uMsg, wParam, lParam);
return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
}
return 0;
}
VOID
COMBOEX_Register (VOID)
{
WNDCLASS32A wndClass;
if (GlobalFindAtom32A (WC_COMBOBOXEX32A)) return;
ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = (WNDPROC32)COMBOEX_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(COMBOEX_INFO *);
wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
wndClass.hbrBackground = (HBRUSH32)(COLOR_WINDOW + 1);
wndClass.lpszClassName = WC_COMBOBOXEX32A;
RegisterClass32A (&wndClass);
}
VOID
COMBOEX_Unregister (VOID)
{
if (GlobalFindAtom32A (WC_COMBOBOXEX32A))
UnregisterClass32A (WC_COMBOBOXEX32A, (HINSTANCE32)NULL);
}
wine-981025/dlls/comctl32/comctl32undoc.c 100644 771 771 113130 6614330177 17726 0 ustar julliard julliard /*
* Undocumented functions from COMCTL32.DLL
*
* Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
* 1998 Juergen Schmied <j.schmied@metronet.de>
* NOTES
* All of these functions are UNDOCUMENTED!! And I mean UNDOCUMENTED!!!!
* Do NOT rely on names or contents of undocumented structures and types!!!
* These functions are used by EXPLORER.EXE, IEXPLORE.EXE and
* COMCTL32.DLL (internally).
*
* TODO
* - Add more functions.
* - Write some documentation.
*/
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "windows.h"
#include "commctrl.h"
#include "heap.h"
#include "debug.h"
extern HANDLE32 COMCTL32_hHeap; /* handle to the private heap */
/**************************************************************************
* COMCTL32_11 [COMCTL32.11]
*
* PARAMS
* hdpa1 [I] handle to a dynamic pointer array
* hdpa2 [I] handle to a dynamic pointer array
* dwParam3
* dwParam4
* dwParam5
* dwParam6
*
* NOTES
* No more information available yet!
*/
DWORD WINAPI
COMCTL32_11 (HDPA hdpa1, HDPA hdpa2, DWORD dwParam3,
DWORD dwParam4, DWORD dwParam5, DWORD dwParam6)
{
FIXME (commctrl, "(%p %p %08lx %08lx %08lx %08lx): empty stub\n",
hdpa1, hdpa2, dwParam3, dwParam4, dwParam5, dwParam6);
return 0;
}
/**************************************************************************
* Alloc [COMCTL32.71]
*
* Allocates memory block from the dll's private heap
*
* PARAMS
* dwSize [I] size of the allocated memory block
*
* RETURNS
* Success: pointer to allocated memory block
* Failure: NULL
*/
LPVOID WINAPI
COMCTL32_Alloc (DWORD dwSize)
{
LPVOID lpPtr;
TRACE (commctrl, "(0x%lx)\n", dwSize);
lpPtr = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
TRACE (commctrl, "-- ret=%p\n", lpPtr);
return lpPtr;
}
/**************************************************************************
* ReAlloc [COMCTL32.72]
*
* Changes the size of an allocated memory block or allocates a memory
* block using the dll's private heap.
*
* PARAMS
* lpSrc [I] pointer to memory block which will be resized
* dwSize [I] new size of the memory block.
*
* RETURNS
* Success: pointer to the resized memory block
* Failure: NULL
*
* NOTES
* If lpSrc is a NULL-pointer, then COMCTL32_ReAlloc allocates a memory
* block like COMCTL32_Alloc.
*/
LPVOID WINAPI
COMCTL32_ReAlloc (LPVOID lpSrc, DWORD dwSize)
{
LPVOID lpDest;
TRACE (commctrl, "(%p 0x%08lx)\n", lpSrc, dwSize);
if (lpSrc)
lpDest = HeapReAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, lpSrc, dwSize);
else
lpDest = HeapAlloc (COMCTL32_hHeap, HEAP_ZERO_MEMORY, dwSize);
TRACE (commctrl, "-- ret=%p\n", lpDest);
return lpDest;
}
/**************************************************************************
* Free [COMCTL32.73]
.*
* Frees an allocated memory block from the dll's private heap.
*
* PARAMS
* lpMem [I] pointer to memory block which will be freed
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
COMCTL32_Free (LPVOID lpMem)
{
TRACE (commctrl, "(%p)\n", lpMem);
return HeapFree (COMCTL32_hHeap, 0, lpMem);
}
/**************************************************************************
* GetSize [COMCTL32.74]
*
* Retrieves the size of the specified memory block from the dll's
* private heap.
*
* PARAMS
* lpMem [I] pointer to an allocated memory block
*
* RETURNS
* Success: size of the specified memory block
* Failure: 0
*/
DWORD WINAPI
COMCTL32_GetSize (LPVOID lpMem)
{
TRACE (commctrl, "(%p)\n", lpMem);
return HeapSize (COMCTL32_hHeap, 0, lpMem);
}
/**************************************************************************
* The MRU-API is a set of functions to manipulate MRU(Most Recently Used)
* lists.
*
*
*/
typedef struct tagMRUINFO
{
DWORD dwParam1;
DWORD dwParam2;
DWORD dwParam3;
HKEY hkeyMain;
LPCSTR lpszSubKey;
DWORD dwParam6;
} MRUINFO, *LPMRUINFO;
typedef struct tagMRU
{
DWORD dwParam1; /* some kind of flag */
DWORD dwParam2;
DWORD dwParam3;
HKEY hkeyMRU;
LPCSTR lpszSubKey;
DWORD dwParam6;
} MRU, *HMRU;
LPVOID WINAPI
CreateMRUListEx32A (LPMRUINFO lpmi, DWORD dwParam2,
DWORD dwParam3, DWORD dwParam4);
/**************************************************************************
* CreateMRUListA [COMCTL32.151]
*
* PARAMS
* dwParam
*
* RETURNS
*/
LPVOID WINAPI
CreateMRUList32A (LPMRUINFO lpmi)
{
return CreateMRUListEx32A (lpmi, 0, 0, 0);
}
DWORD WINAPI
FreeMRUList32A (HMRU hmru)
{
FIXME (commctrl, "(%p) empty stub!\n", hmru);
#if 0
if (!(hmru->dwParam1 & 1001)) {
RegSetValueEx32A (hmru->hKeyMRU, "MRUList", 0, REG_SZ,
hmru->lpszMRUString,
lstrlen32A (hmru->lpszMRUString));
}
RegClosKey32 (hmru->hkeyMRU
COMCTL32_Free32 (hmru->lpszMRUString);
#endif
return COMCTL32_Free (hmru);
}
DWORD WINAPI
AddMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
FIXME (commctrl, "(%lx %lx %lx) empty stub!\n",
dwParam1, dwParam2, dwParam3);
return 0;
}
DWORD WINAPI
FindMRUData (DWORD dwParam1, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
{
FIXME (commctrl, "(%lx %lx %lx %lx) empty stub!\n",
dwParam1, dwParam2, dwParam3, dwParam4);
return TRUE;
}
LPVOID WINAPI
CreateMRUListEx32A (LPMRUINFO lpmi, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
{
DWORD dwLocal1;
HKEY hkeyResult;
DWORD dwLocal3;
LPVOID lMRU;
DWORD dwLocal5;
DWORD dwLocal6;
DWORD dwLocal7;
DWORD dwDisposition;
/* internal variables */
LPVOID ptr;
FIXME (commctrl, "(%p) empty stub!\n", lpmi);
if (lpmi) {
FIXME (commctrl, "(%lx %lx %lx %lx \"%s\" %lx)\n",
lpmi->dwParam1, lpmi->dwParam2, lpmi->dwParam3,
lpmi->hkeyMain, lpmi->lpszSubKey, lpmi->dwParam6);
}
/* dummy pointer creation */
ptr = COMCTL32_Alloc (32);
FIXME (commctrl, "-- ret = %p\n", ptr);
return ptr;
}
/**************************************************************************
* Str_GetPtrA [COMCTL32.233]
*
* PARAMS
* lpSrc [I]
* lpDest [O]
* nMaxLen [I]
*
* RETURNS
*/
INT32 WINAPI
Str_GetPtr32A (LPCSTR lpSrc, LPSTR lpDest, INT32 nMaxLen)
{
INT32 len;
TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
if (!lpDest && lpSrc)
return lstrlen32A (lpSrc);
if (nMaxLen == 0)
return 0;
if (lpSrc == NULL) {
lpDest[0] = '\0';
return 0;
}
len = lstrlen32A (lpSrc);
if (len >= nMaxLen)
len = nMaxLen - 1;
RtlMoveMemory (lpDest, lpSrc, len);
lpDest[len] = '\0';
return len;
}
/**************************************************************************
* Str_SetPtrA [COMCTL32.234]
*
* PARAMS
* lppDest [O]
* lpSrc [I]
*
* RETURNS
*/
BOOL32 WINAPI
Str_SetPtr32A (LPSTR *lppDest, LPCSTR lpSrc)
{
TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
if (lpSrc) {
LPSTR ptr = COMCTL32_ReAlloc (lppDest, lstrlen32A (lpSrc) + 1);
if (!ptr)
return FALSE;
lstrcpy32A (ptr, lpSrc);
*lppDest = ptr;
}
else {
if (*lppDest) {
COMCTL32_Free (*lppDest);
*lppDest = NULL;
}
}
return TRUE;
}
/**************************************************************************
* Str_GetPtrW [COMCTL32.235]
*
* PARAMS
* lpSrc [I]
* lpDest [O]
* nMaxLen [I]
*
* RETURNS
*/
INT32 WINAPI
Str_GetPtr32W (LPCWSTR lpSrc, LPWSTR lpDest, INT32 nMaxLen)
{
INT32 len;
TRACE (commctrl, "(%p %p %d)\n", lpSrc, lpDest, nMaxLen);
if (!lpDest && lpSrc)
return lstrlen32W (lpSrc);
if (nMaxLen == 0)
return 0;
if (lpSrc == NULL) {
lpDest[0] = L'\0';
return 0;
}
len = lstrlen32W (lpSrc);
if (len >= nMaxLen)
len = nMaxLen - 1;
RtlMoveMemory (lpDest, lpSrc, len*sizeof(WCHAR));
lpDest[len] = L'\0';
return len;
}
/**************************************************************************
* Str_SetPtrW [COMCTL32.236]
*
* PARAMS
* lpDest [O]
* lpSrc [I]
*
* RETURNS
*/
BOOL32 WINAPI
Str_SetPtr32W (LPWSTR *lppDest, LPCWSTR lpSrc)
{
TRACE (commctrl, "(%p %p)\n", lppDest, lpSrc);
if (lpSrc) {
INT32 len = lstrlen32W (lpSrc) + 1;
LPWSTR ptr = COMCTL32_ReAlloc (lppDest, len * sizeof(WCHAR));
if (!ptr)
return FALSE;
lstrcpy32W (ptr, lpSrc);
*lppDest = ptr;
}
else {
if (*lppDest) {
COMCTL32_Free (*lppDest);
*lppDest = NULL;
}
}
return TRUE;
}
/**************************************************************************
* The DSA-API is a set of functions to create and manipulate arrays of
* fix sized memory blocks. These arrays can store any kind of data
* (strings, icons...).
*/
/**************************************************************************
* DSA_Create [COMCTL32.320] Creates a dynamic storage array
*
* PARAMS
* nSize [I] size of the array elements
* nGrow [I] number of elements by which the array grows when it is filled
*
* RETURNS
* Success: pointer to a array control structure. use this like a handle.
* Failure: NULL
*/
HDSA WINAPI
DSA_Create (INT32 nSize, INT32 nGrow)
{
HDSA hdsa;
TRACE (commctrl, "(size=%d grow=%d)\n", nSize, nGrow);
hdsa = (HDSA)COMCTL32_Alloc (sizeof(DSA));
if (hdsa)
{
hdsa->nItemCount = 0;
hdsa->pData = NULL;
hdsa->nMaxCount = 0;
hdsa->nItemSize = nSize;
hdsa->nGrow = MAX(1, nGrow);
}
return hdsa;
}
/**************************************************************************
* DSA_Destroy [COMCTL32.321] Destroys a dynamic storage array
*
* PARAMS
* hdsa [I] pointer to the array control structure
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DSA_Destroy (const HDSA hdsa)
{
TRACE (commctrl, "(%p)\n", hdsa);
if (!hdsa)
return FALSE;
if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
return FALSE;
return COMCTL32_Free (hdsa);
}
/**************************************************************************
* DSA_GetItem [COMCTL32.322]
*
* PARAMS
* hdsa [I] pointer to the array control structure
* nIndex [I] number of the Item to get
* pDest [O] destination buffer. Has to be >= dwElementSize.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DSA_GetItem (const HDSA hdsa, INT32 nIndex, LPVOID pDest)
{
LPVOID pSrc;
TRACE (commctrl, "(%p %d %p)\n", hdsa, nIndex, pDest);
if (!hdsa)
return FALSE;
if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
return FALSE;
pSrc = hdsa->pData + (hdsa->nItemSize * nIndex);
memmove (pDest, pSrc, hdsa->nItemSize);
return TRUE;
}
/**************************************************************************
* DSA_GetItemPtr [COMCTL32.323]
*
* Retrieves a pointer to the specified item.
*
* PARAMS
* hdsa [I] pointer to the array control structure
* nIndex [I] index of the desired item
*
* RETURNS
* Success: pointer to an item
* Failure: NULL
*/
LPVOID WINAPI
DSA_GetItemPtr (const HDSA hdsa, INT32 nIndex)
{
LPVOID pSrc;
TRACE (commctrl, "(%p %d)\n", hdsa, nIndex);
if (!hdsa)
return NULL;
if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
return NULL;
pSrc = hdsa->pData + (hdsa->nItemSize * nIndex);
TRACE (commctrl, "-- ret=%p\n", pSrc);
return pSrc;
}
/**************************************************************************
* DSA_SetItem [COMCTL32.325]
*
* Sets the contents of an item in the array.
*
* PARAMS
* hdsa [I] pointer to the array control structure
* nIndex [I] index for the item
* pSrc [I] pointer to the new item data
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DSA_SetItem (const HDSA hdsa, INT32 nIndex, LPVOID pSrc)
{
INT32 nSize, nNewItems;
LPVOID pDest, lpTemp;
TRACE (commctrl, "(%p %d %p)\n", hdsa, nIndex, pSrc);
if ((!hdsa) || nIndex < 0)
return FALSE;
if (hdsa->nItemCount <= nIndex) {
/* within the old array */
if (hdsa->nMaxCount > nIndex) {
/* within the allocated space, set a new boundary */
hdsa->nItemCount = nIndex;
}
else {
/* resize the block of memory */
nNewItems =
hdsa->nGrow * ((INT32)((nIndex - 1) / hdsa->nGrow) + 1);
nSize = hdsa->nItemSize * nNewItems;
lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
if (!lpTemp)
return FALSE;
hdsa->nMaxCount = nNewItems;
hdsa->pData = lpTemp;
}
}
/* put the new entry in */
pDest = hdsa->pData + (hdsa->nItemSize * nIndex);
TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
pDest, pSrc, hdsa->nItemSize);
memmove (pDest, pSrc, hdsa->nItemSize);
return TRUE;
}
/**************************************************************************
* DSA_InsertItem [COMCTL32.325]
*
* PARAMS
* hdsa [I] pointer to the array control structure
* nIndex [I] index for the new item
* pSrc [I] pointer to the element
*
* RETURNS
* Success: position of the new item
* Failure: -1
*/
INT32 WINAPI
DSA_InsertItem (const HDSA hdsa, INT32 nIndex, LPVOID pSrc)
{
INT32 nNewItems, nSize, i;
LPVOID lpTemp, lpDest;
LPDWORD p;
TRACE(commctrl, "(%p %d %p)\n", hdsa, nIndex, pSrc);
if ((!hdsa) || nIndex < 0)
return -1;
for (i = 0; i < hdsa->nItemSize; i += 4) {
p = *(DWORD**)(pSrc + i);
if (IsBadStringPtr32A ((char*)p, 256))
TRACE (commctrl, "-- %d=%p\n", i, (DWORD*)p);
else
TRACE (commctrl, "-- %d=%p [%s]\n", i, p, debugstr_a((char*)p));
}
/* when nIndex > nItemCount then append */
if (nIndex >= hdsa->nItemCount)
nIndex = hdsa->nItemCount;
/* do we need to resize ? */
if (hdsa->nItemCount >= hdsa->nMaxCount) {
nNewItems = hdsa->nMaxCount + hdsa->nGrow;
nSize = hdsa->nItemSize * nNewItems;
lpTemp = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
if (!lpTemp)
return -1;
hdsa->nMaxCount = nNewItems;
hdsa->pData = lpTemp;
}
/* do we need to move elements ? */
if (nIndex < hdsa->nItemCount) {
lpTemp = hdsa->pData + (hdsa->nItemSize * nIndex);
lpDest = lpTemp + hdsa->nItemSize;
nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
lpDest, lpTemp, nSize);
memmove (lpDest, lpTemp, nSize);
}
/* ok, we can put the new Item in */
hdsa->nItemCount++;
lpDest = hdsa->pData + (hdsa->nItemSize * nIndex);
TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
lpDest, pSrc, hdsa->nItemSize);
memmove (lpDest, pSrc, hdsa->nItemSize);
return hdsa->nItemCount;
}
/**************************************************************************
* DSA_DeleteItem [COMCTL32.326]
*
* PARAMS
* hdsa [I] pointer to the array control structure
* nIndex [I] index for the element to delete
*
* RETURNS
* Success: number of the deleted element
* Failure: -1
*/
INT32 WINAPI
DSA_DeleteItem (const HDSA hdsa, INT32 nIndex)
{
LPVOID lpDest,lpSrc;
INT32 nSize;
TRACE (commctrl, "(%p %d)\n", hdsa, nIndex);
if (!hdsa)
return -1;
if (nIndex < 0 || nIndex >= hdsa->nItemCount)
return -1;
/* do we need to move ? */
if (nIndex < hdsa->nItemCount - 1) {
lpDest = hdsa->pData + (hdsa->nItemSize * nIndex);
lpSrc = lpDest + hdsa->nItemSize;
nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
TRACE (commctrl, "-- move dest=%p src=%p size=%d\n",
lpDest, lpSrc, nSize);
memmove (lpDest, lpSrc, nSize);
}
hdsa->nItemCount--;
/* free memory ? */
if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
nSize = hdsa->nItemSize * hdsa->nItemCount;
lpDest = (LPVOID)COMCTL32_ReAlloc (hdsa->pData, nSize);
if (!lpDest)
return -1;
hdsa->nMaxCount = hdsa->nItemCount;
hdsa->pData = lpDest;
}
return nIndex;
}
/**************************************************************************
* DSA_DeleteAllItems [COMCTL32.326]
*
* Removes all items and reinitializes the array.
*
* PARAMS
* hdsa [I] pointer to the array control structure
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DSA_DeleteAllItems (const HDSA hdsa)
{
TRACE (commctrl, "(%p)\n", hdsa);
if (!hdsa)
return FALSE;
if (hdsa->pData && (!COMCTL32_Free (hdsa->pData)))
return FALSE;
hdsa->nItemCount = 0;
hdsa->pData = NULL;
hdsa->nMaxCount = 0;
return TRUE;
}
/**************************************************************************
* The DPA-API is a set of functions to create and manipulate arrays of
* pointers.
*/
/**************************************************************************
* DPA_Create [COMCTL32.328] Creates a dynamic pointer array
*
* PARAMS
* nGrow [I] number of items by which the array grows when it is filled
*
* RETURNS
* Success: handle (pointer) to the pointer array.
* Failure: NULL
*/
HDPA WINAPI
DPA_Create (INT32 nGrow)
{
HDPA hdpa;
TRACE (commctrl, "(%d)\n", nGrow);
hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
if (hdpa) {
hdpa->nGrow = MAX(8, nGrow);
hdpa->hHeap = COMCTL32_hHeap;
hdpa->nMaxCount = hdpa->nGrow * 2;
hdpa->ptrs =
(LPVOID*)COMCTL32_Alloc (hdpa->nMaxCount * sizeof(LPVOID));
}
TRACE (commctrl, "-- %p\n", hdpa);
return hdpa;
}
/**************************************************************************
* DPA_Destroy [COMCTL32.329] Destroys a dynamic pointer array
*
* PARAMS
* hdpa [I] handle (pointer) to the pointer array
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DPA_Destroy (const HDPA hdpa)
{
TRACE (commctrl, "(%p)\n", hdpa);
if (!hdpa)
return FALSE;
if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
return FALSE;
return HeapFree (hdpa->hHeap, 0, hdpa);
}
/**************************************************************************
* DPA_Grow [COMCTL32.330]
*
* Sets the growth amount.
*
* PARAMS
* hdpa [I] handle (pointer) to the existing (source) pointer array
* nGrow [I] number of items, the array grows, when it's too small
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DPA_Grow (const HDPA hdpa, INT32 nGrow)
{
TRACE (commctrl, "(%p %d)\n", hdpa, nGrow);
if (!hdpa)
return FALSE;
hdpa->nGrow = MAX(8, nGrow);
return TRUE;
}
/**************************************************************************
* DPA_Clone [COMCTL32.331]
*
* Copies a pointer array to an other one or creates a copy
*
* PARAMS
* hdpa [I] handle (pointer) to the existing (source) pointer array
* hdpaNew [O] handle (pointer) to the destination pointer array
*
* RETURNS
* Success: pointer to the destination pointer array.
* Failure: NULL
*
* NOTES
* - If the 'hdpaNew' is a NULL-Pointer, a copy of the source pointer
* array will be created and it's handle (pointer) is returned.
* - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
* this implementation just returns NULL.
*/
HDPA WINAPI
DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
{
INT32 nNewItems, nSize;
HDPA hdpaTemp;
if (!hdpa)
return NULL;
TRACE (commctrl, "(%p %p)\n", hdpa, hdpaNew);
if (!hdpaNew) {
/* create a new DPA */
hdpaTemp = (HDPA)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
sizeof(DPA));
hdpaTemp->hHeap = hdpa->hHeap;
hdpaTemp->nGrow = hdpa->nGrow;
}
else
hdpaTemp = hdpaNew;
if (hdpaTemp->ptrs) {
/* remove old pointer array */
HeapFree (hdpaTemp->hHeap, 0, hdpaTemp->ptrs);
hdpaTemp->ptrs = NULL;
hdpaTemp->nItemCount = 0;
hdpaTemp->nMaxCount = 0;
}
/* create a new pointer array */
nNewItems = hdpaTemp->nGrow *
((INT32)((hdpa->nItemCount - 1) / hdpaTemp->nGrow) + 1);
nSize = nNewItems * sizeof(LPVOID);
hdpaTemp->ptrs =
(LPVOID*)HeapAlloc (hdpaTemp->hHeap, HEAP_ZERO_MEMORY, nSize);
hdpaTemp->nMaxCount = nNewItems;
/* clone the pointer array */
hdpaTemp->nItemCount = hdpa->nItemCount;
memmove (hdpaTemp->ptrs, hdpa->ptrs,
hdpaTemp->nItemCount * sizeof(LPVOID));
return hdpaTemp;
}
/**************************************************************************
* DPA_GetPtr [COMCTL32.332]
*
* Retrieves a pointer from a dynamic pointer array
*
* PARAMS
* hdpa [I] handle (pointer) to the pointer array
* nIndex [I] array index of the desired pointer
*
* RETURNS
* Success: pointer
* Failure: NULL
*/
LPVOID WINAPI
DPA_GetPtr (const HDPA hdpa, INT32 i)
{
TRACE (commctrl, "(%p %d)\n", hdpa, i);
if (!hdpa)
return NULL;
if (!hdpa->ptrs)
return NULL;
if ((i < 0) || (i >= hdpa->nItemCount))
return NULL;
TRACE (commctrl, "-- %p\n", hdpa->ptrs[i]);
return hdpa->ptrs[i];
}
/**************************************************************************
* DPA_GetPtrIndex [COMCTL32.333]
*
* Retrieves the index of the specified pointer
*
* PARAMS
* hdpa [I] handle (pointer) to the pointer array
* p [I] pointer
*
* RETURNS
* Success: index of the specified pointer
* Failure: -1
*/
INT32 WINAPI
DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
{
INT32 i;
if (!hdpa->ptrs)
return -1;
for (i = 0; i < hdpa->nItemCount; i++) {
if (hdpa->ptrs[i] == p)
return i;
}
return -1;
}
/**************************************************************************
* DPA_InsertPtr [COMCTL32.334]
*
* Inserts a pointer into a dynamic pointer array
*
* PARAMS
* hdpa [I] handle (pointer) to the array
* i [I] array index
* p [I] pointer to insert
*
* RETURNS
* Success: index of the inserted pointer
* Failure: -1
*/
INT32 WINAPI
DPA_InsertPtr (const HDPA hdpa, INT32 i, LPVOID p)
{
INT32 nNewItems, nSize, nIndex = 0;
LPVOID *lpTemp, *lpDest;
TRACE (commctrl, "(%p %d %p)\n", hdpa, i, p);
if ((!hdpa) || (i < 0))
return -1;
if (!hdpa->ptrs) {
hdpa->ptrs =
(LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
2 * hdpa->nGrow * sizeof(LPVOID));
if (!hdpa->ptrs)
return -1;
hdpa->nMaxCount = hdpa->nGrow * 2;
nIndex = 0;
}
else {
if (hdpa->nItemCount >= hdpa->nMaxCount) {
TRACE (commctrl, "-- resizing\n");
nNewItems = hdpa->nMaxCount + hdpa->nGrow;
nSize = nNewItems * sizeof(LPVOID);
lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
hdpa->ptrs, nSize);
if (!lpTemp)
return -1;
hdpa->nMaxCount = nNewItems;
hdpa->ptrs = lpTemp;
}
if (i >= hdpa->nItemCount) {
nIndex = hdpa->nItemCount;
TRACE (commctrl, "-- appending at %d\n", nIndex);
}
else {
TRACE (commctrl, "-- inserting at %d\n", i);
lpTemp = hdpa->ptrs + (sizeof(LPVOID) * i);
lpDest = lpTemp + sizeof(LPVOID);
nSize = (hdpa->nItemCount - i) * sizeof(LPVOID);
TRACE (commctrl, "-- move dest=%p src=%p size=%x\n",
lpDest, lpTemp, nSize);
memmove (lpDest, lpTemp, nSize);
nIndex = i;
}
}
/* insert item */
hdpa->nItemCount++;
hdpa->ptrs[nIndex] = p;
return nIndex;
}
/**************************************************************************
* DPA_SetPtr [COMCTL32.335]
*
* Sets a pointer in the pointer array
*
* PARAMS
* hdpa [I] handle (pointer) to the pointer array
* i [I] index of the pointer that will be set
* p [I] pointer to be set
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DPA_SetPtr (const HDPA hdpa, INT32 i, LPVOID p)
{
LPVOID *lpTemp;
TRACE (commctrl, "(%p %d %p)\n", hdpa, i, p);
if ((!hdpa) || i < 0)
return FALSE;
if (hdpa->nItemCount <= i) {
/* within the old array */
if (hdpa->nMaxCount > i) {
/* within the allocated space, set a new boundary */
hdpa->nItemCount = i;
}
else {
/* resize the block of memory */
INT32 nNewItems =
hdpa->nGrow * ((INT32)((i - 1) / hdpa->nGrow) + 1);
INT32 nSize = nNewItems * sizeof(LPVOID);
lpTemp = (LPVOID*)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
hdpa->ptrs, nSize);
if (!lpTemp)
return FALSE;
hdpa->nItemCount = nNewItems;
hdpa->ptrs = lpTemp;
}
}
/* put the new entry in */
hdpa->ptrs[i] = p;
return TRUE;
}
/**************************************************************************
* DPA_DeletePtr [COMCTL32.336]
*
* Removes a pointer from the pointer array.
*
* PARAMS
* hdpa [I] handle (pointer) to the pointer array
* i [I] index of the pointer that will be deleted
*
* RETURNS
* Success: deleted pointer
* Failure: NULL
*/
LPVOID WINAPI
DPA_DeletePtr (const HDPA hdpa, INT32 i)
{
LPVOID lpDest, lpSrc, lpTemp = NULL;
INT32 nSize;
TRACE (commctrl, "(%p %d)\n", hdpa, i);
if ((!hdpa) || i < 0 || i >= hdpa->nItemCount)
return NULL;
lpTemp = hdpa->ptrs[i];
/* do we need to move ?*/
if (i < hdpa->nItemCount - 1) {
lpDest = hdpa->ptrs + (i * sizeof (LPVOID));
lpSrc = lpDest + sizeof(LPVOID);
nSize = (hdpa->nItemCount - i - 1) * sizeof(LPVOID);
TRACE (commctrl,"-- move dest=%p src=%p size=%x\n",
lpDest, lpSrc, nSize);
memmove (lpDest, lpSrc, nSize);
}
hdpa->nItemCount --;
/* free memory ?*/
if ((hdpa->nMaxCount - hdpa->nItemCount) >= hdpa->nGrow) {
INT32 nNewItems = MIN(hdpa->nGrow * 2, hdpa->nItemCount);
nSize = nNewItems * sizeof(LPVOID);
lpDest = (LPVOID)HeapReAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
hdpa->ptrs, nSize);
if (!lpDest)
return NULL;
hdpa->nMaxCount = nNewItems;
hdpa->ptrs = (LPVOID*)lpDest;
}
return lpTemp;
}
/**************************************************************************
* DPA_DeleteAllPtrs [COMCTL32.337]
*
* Removes all pointers and reinitializes the array.
*
* PARAMS
* hdpa [I] handle (pointer) to the pointer array
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DPA_DeleteAllPtrs (const HDPA hdpa)
{
TRACE (commctrl, "(%p)\n", hdpa);
if (!hdpa)
return FALSE;
if (hdpa->ptrs && (!HeapFree (hdpa->hHeap, 0, hdpa->ptrs)))
return FALSE;
hdpa->nItemCount = 0;
hdpa->nMaxCount = hdpa->nGrow * 2;
hdpa->ptrs = (LPVOID*)HeapAlloc (hdpa->hHeap, HEAP_ZERO_MEMORY,
hdpa->nMaxCount * sizeof(LPVOID));
return TRUE;
}
/**************************************************************************
* DPA_QuickSort [Internal]
*
* Ordinary quicksort (used by DPA_Sort).
*
* PARAMS
* lpPtrs [I] pointer to the pointer array
* l [I] index of the "left border" of the partition
* r [I] index of the "right border" of the partition
* pfnCompare [I] pointer to the compare function
* lParam [I] user defined value (3rd parameter in compare function)
*
* RETURNS
* NONE
*/
static VOID
DPA_QuickSort (LPVOID *lpPtrs, INT32 l, INT32 r,
PFNDPACOMPARE pfnCompare, LPARAM lParam)
{
LPVOID t, v;
INT32 i, j;
TRACE (commctrl, "l=%i r=%i\n", l, r);
i = l;
j = r;
v = lpPtrs[(int)(l+r)/2];
do {
while ((pfnCompare)(lpPtrs[i], v, lParam) < 0) i++;
while ((pfnCompare)(lpPtrs[j], v, lParam) > 0) j--;
if (i <= j)
{
t = lpPtrs[i];
lpPtrs[i++] = lpPtrs[j];
lpPtrs[j--] = t;
}
} while (i <= j);
if (l < j) DPA_QuickSort (lpPtrs, l, j, pfnCompare, lParam);
if (i < r) DPA_QuickSort (lpPtrs, i, r, pfnCompare, lParam);
}
/**************************************************************************
* DPA_Sort [COMCTL32.338]
*
* Sorts a pointer array using a user defined compare function
*
* PARAMS
* hdpa [I] handle (pointer) to the pointer array
* pfnCompare [I] pointer to the compare function
* lParam [I] user defined value (3rd parameter of compare function)
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
{
if (!hdpa || !pfnCompare)
return FALSE;
TRACE (commctrl, "(%p %p 0x%lx)\n", hdpa, pfnCompare, lParam);
if ((hdpa->nItemCount > 1) && (hdpa->ptrs))
DPA_QuickSort (hdpa->ptrs, 0, hdpa->nItemCount - 1,
pfnCompare, lParam);
return TRUE;
}
/**************************************************************************
* DPA_Search [COMCTL32.339]
*
* Searches a pointer array for a specified pointer
*
* PARAMS
* hdpa [I] handle (pointer) to the pointer array
* pFind [I] pointer to search for
* nStart [I] start index
* pfnCompare [I] pointer to the compare function
* lParam [I] user defined value (3rd parameter of compare function)
* uOptions [I] search options
*
* RETURNS
* Success: index of the pointer in the array.
* Failure: -1
*
* NOTES
* Binary search taken from R.Sedgewick "Algorithms in C"!
* Function is NOT tested!
* If something goes wrong, blame HIM not ME! (Eric Kohl)
*/
INT32 WINAPI
DPA_Search (const HDPA hdpa, LPVOID pFind, INT32 nStart,
PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT32 uOptions)
{
if (!hdpa || !pfnCompare || !pFind)
return -1;
TRACE (commctrl, "(%p %p %d %p 0x%08lx 0x%08x)\n",
hdpa, pFind, nStart, pfnCompare, lParam, uOptions);
if (uOptions & DPAS_SORTED) {
/* array is sorted --> use binary search */
INT32 l, r, x, n;
LPVOID *lpPtr;
TRACE (commctrl, "binary search\n");
l = (nStart == -1) ? 0 : nStart;
r = hdpa->nItemCount - 1;
lpPtr = hdpa->ptrs;
while (r >= l) {
x = (l + r) / 2;
n = (pfnCompare)(pFind, lpPtr[x], lParam);
if (n < 0)
r = x - 1;
else
l = x + 1;
if (n == 0) {
TRACE (commctrl, "-- ret=%d\n", n);
return n;
}
}
if (uOptions & DPAS_INSERTBEFORE) {
TRACE (commctrl, "-- ret=%d\n", r);
return r;
}
if (uOptions & DPAS_INSERTAFTER) {
TRACE (commctrl, "-- ret=%d\n", l);
return l;
}
}
else {
/* array is not sorted --> use linear search */
LPVOID *lpPtr;
INT32 nIndex;
TRACE (commctrl, "linear search\n");
nIndex = (nStart == -1)? 0 : nStart;
lpPtr = hdpa->ptrs;
for (; nIndex < hdpa->nItemCount; nIndex++) {
if ((pfnCompare)(pFind, lpPtr[nIndex], lParam) == 0) {
TRACE (commctrl, "-- ret=%d\n", nIndex);
return nIndex;
}
}
}
TRACE (commctrl, "-- not found: ret=-1\n");
return -1;
}
/**************************************************************************
* DPA_CreateEx [COMCTL32.340]
*
* Creates a dynamic pointer array using the specified size and heap.
*
* PARAMS
* nGrow [I] number of items by which the array grows when it is filled
* hHeap [I] handle to the heap where the array is stored
*
* RETURNS
* Success: handle (pointer) to the pointer array.
* Failure: NULL
*/
HDPA WINAPI
DPA_CreateEx (INT32 nGrow, HANDLE32 hHeap)
{
HDPA hdpa;
TRACE (commctrl, "(%d 0x%x)\n", nGrow, hHeap);
if (hHeap)
hdpa = (HDPA)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, sizeof(DPA));
else
hdpa = (HDPA)COMCTL32_Alloc (sizeof(DPA));
if (hdpa) {
hdpa->nGrow = MIN(8, nGrow);
hdpa->hHeap = hHeap ? hHeap : COMCTL32_hHeap;
hdpa->nMaxCount = hdpa->nGrow * 2;
hdpa->ptrs =
(LPVOID*)HeapAlloc (hHeap, HEAP_ZERO_MEMORY,
hdpa->nMaxCount * sizeof(LPVOID));
}
TRACE (commctrl, "-- %p\n", hdpa);
return hdpa;
}
/**************************************************************************
* Notification functions
*/
typedef struct tagNOTIFYDATA
{
HWND32 hwndFrom;
HWND32 hwndTo;
DWORD dwParam3;
DWORD dwParam4;
DWORD dwParam5;
DWORD dwParam6;
} NOTIFYDATA, *LPNOTIFYDATA;
/**************************************************************************
* DoNotify [Internal]
*/
static LRESULT
DoNotify (LPNOTIFYDATA lpNotify, UINT32 uCode, LPNMHDR lpHdr)
{
NMHDR nmhdr;
LPNMHDR lpNmh = NULL;
UINT32 idFrom = 0;
TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
lpNotify->hwndFrom, lpNotify->hwndTo, uCode, lpHdr,
lpNotify->dwParam5);
if (!lpNotify->hwndTo)
return 0;
if (lpNotify->hwndFrom == -1) {
lpNmh = lpHdr;
idFrom = lpHdr->idFrom;
}
else {
if (lpNotify->hwndFrom) {
HWND32 hwndParent = GetParent32 (lpNotify->hwndFrom);
if (hwndParent) {
hwndParent = GetWindow32 (lpNotify->hwndFrom, GW_OWNER);
if (hwndParent)
idFrom = GetDlgCtrlID32 (lpNotify->hwndFrom);
}
}
lpNmh = (lpHdr) ? lpHdr : &nmhdr;
lpNmh->hwndFrom = lpNotify->hwndFrom;
lpNmh->idFrom = idFrom;
lpNmh->code = uCode;
}
return SendMessage32A (lpNotify->hwndTo, WM_NOTIFY, idFrom, (LPARAM)lpNmh);
}
/**************************************************************************
* SendNotify [COMCTL32.341]
*
* PARAMS
* hwndFrom [I]
* hwndTo [I]
* uCode [I]
* lpHdr [I]
*
* RETURNS
* Success: return value from notification
* Failure: 0
*/
LRESULT WINAPI
COMCTL32_SendNotify (HWND32 hwndFrom, HWND32 hwndTo,
UINT32 uCode, LPNMHDR lpHdr)
{
NOTIFYDATA notify;
TRACE (commctrl, "(0x%04x 0x%04x %d %p)\n",
hwndFrom, hwndTo, uCode, lpHdr);
notify.hwndFrom = hwndFrom;
notify.hwndTo = hwndTo;
notify.dwParam5 = 0;
notify.dwParam6 = 0;
return DoNotify (¬ify, uCode, lpHdr);
}
/**************************************************************************
* SendNotifyEx [COMCTL32.342]
*
* PARAMS
* hwndFrom [I]
* hwndTo [I]
* uCode [I]
* lpHdr [I]
* dwParam5 [I]
*
* RETURNS
* Success: return value from notification
* Failure: 0
*/
LRESULT WINAPI
COMCTL32_SendNotifyEx (HWND32 hwndTo, HWND32 hwndFrom, UINT32 uCode,
LPNMHDR lpHdr, DWORD dwParam5)
{
NOTIFYDATA notify;
HWND32 hwndNotify;
TRACE (commctrl, "(0x%04x 0x%04x %d %p 0x%08lx)\n",
hwndFrom, hwndTo, uCode, lpHdr, dwParam5);
hwndNotify = hwndTo;
if (!hwndTo) {
if (IsWindow32 (hwndFrom)) {
hwndNotify = GetParent32 (hwndFrom);
if (!hwndNotify)
return 0;
}
}
notify.hwndFrom = hwndFrom;
notify.hwndTo = hwndNotify;
notify.dwParam5 = dwParam5;
notify.dwParam6 = 0;
return DoNotify (¬ify, uCode, lpHdr);
}
/**************************************************************************
* StrChrA [COMCTL32.350]
*
*/
LPSTR WINAPI
COMCTL32_StrChrA (LPCSTR lpString, CHAR cChar)
{
return strchr (lpString, cChar);
}
/**************************************************************************
* StrStrIA [COMCTL32.355]
*/
LPSTR WINAPI
COMCTL32_StrStrIA (LPCSTR lpStr1, LPCSTR lpStr2)
{
INT32 len1, len2, i;
CHAR first;
if (*lpStr2 == 0)
return ((LPSTR)lpStr1);
len1 = 0;
while (lpStr1[len1] != 0) ++len1;
len2 = 0;
while (lpStr2[len2] != 0) ++len2;
if (len2 == 0)
return ((LPSTR)(lpStr1 + len1));
first = tolower (*lpStr2);
while (len1 >= len2) {
if (tolower(*lpStr1) == first) {
for (i = 1; i < len2; ++i)
if (tolower (lpStr1[i]) != tolower(lpStr2[i]))
break;
if (i >= len2)
return ((LPSTR)lpStr1);
}
++lpStr1; --len1;
}
return (NULL);
}
/**************************************************************************
* StrToIntA [COMCTL32.357] Converts a string to a signed integer.
*/
INT32 WINAPI
COMCTL32_StrToIntA (LPSTR lpString)
{
return atoi(lpString);
}
/**************************************************************************
* COMCTL32_385 [COMCTL32.385]
*
* Enumerates all items in a dynamic pointer array.
*
* PARAMS
* hdpa [I] handle to the dynamic pointer array
* enumProc [I]
* dwParam3 [I]
*
* RETURNS
* none
*
* NOTES
* Original function name unknown!
*/
typedef DWORD (CALLBACK *DPAENUMPROC)(LPVOID, DWORD);
VOID WINAPI
COMCTL32_385 (HDPA hdpa, DPAENUMPROC enumProc, DWORD dwParam3)
{
INT32 i;
TRACE (commctrl, "(%p %p %08lx)\n", hdpa, enumProc, dwParam3);
if (!hdpa)
return;
if (hdpa->nItemCount <= 0)
return;
for (i = 0; i < hdpa->nItemCount; i++) {
if ((enumProc)(hdpa->ptrs[i], dwParam3) == 0)
return;
}
return;
}
/**************************************************************************
* COMCTL32_386 [COMCTL32.386]
*
* Enumerates all items in a dynamic pointer array and destroys it.
*
* PARAMS
* hdpa [I] handle to the dynamic pointer array
* enumProc [I]
* dwParam3 [I]
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* NOTES
* Original function name unknown!
*/
BOOL32 WINAPI
COMCTL32_386 (HDPA hdpa, DPAENUMPROC enumProc, DWORD dwParam3)
{
TRACE (commctrl, "(%p %p %08lx)\n", hdpa, enumProc, dwParam3);
COMCTL32_385 (hdpa, enumProc, dwParam3);
return DPA_Destroy (hdpa);
}
/**************************************************************************
* COMCTL32_387 [COMCTL32.387]
*
* Enumerates all items in a dynamic storage array.
*
* PARAMS
* hdsa [I] handle to the dynamic storage array
* enumProc [I]
* dwParam3 [I]
*
* RETURNS
* none
*
* NOTES
* Original function name unknown!
*/
typedef DWORD (CALLBACK *DSAENUMPROC)(LPVOID, DWORD);
VOID WINAPI
COMCTL32_387 (HDSA hdsa, DSAENUMPROC enumProc, DWORD dwParam3)
{
INT32 i;
TRACE (commctrl, "(%p %p %08lx)\n", hdsa, enumProc, dwParam3);
if (!hdsa)
return;
if (hdsa->nItemCount <= 0)
return;
for (i = 0; i < hdsa->nItemCount; i++) {
LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
if ((enumProc)(lpItem, dwParam3) == 0)
return;
}
return;
}
/**************************************************************************
* COMCTL32_388 [COMCTL32.388]
*
* Enumerates all items in a dynamic storage array and destroys it.
*
* PARAMS
* hdsa [I] handle to the dynamic storage array
* enumProc [I]
* dwParam3 [I]
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* NOTES
* Original function name unknown!
*/
BOOL32 WINAPI
COMCTL32_388 (HDSA hdsa, DSAENUMPROC enumProc, DWORD dwParam3)
{
TRACE (commctrl, "(%p %p %08lx)\n", hdsa, enumProc, dwParam3);
COMCTL32_387 (hdsa, enumProc, dwParam3);
return DSA_Destroy (hdsa);
}
wine-981025/dlls/comctl32/commctrl.c 100644 771 771 45744 6614330267 17066 0 ustar julliard julliard /*
* Common controls functions
*
* Copyright 1997 Dimitrie O. Paun
* Copyright 1998 Eric Kohl
*
*/
#include "win.h"
#include "heap.h"
#include "commctrl.h"
#include "animate.h"
#include "comboex.h"
#include "header.h"
#include "hotkey.h"
#include "ipaddress.h"
#include "listview.h"
#include "nativefont.h"
#include "pager.h"
#include "progress.h"
#include "rebar.h"
#include "status.h"
#include "tab.h"
#include "toolbar.h"
#include "tooltips.h"
#include "trackbar.h"
#include "treeview.h"
#include "updown.h"
#include "debug.h"
#include "winerror.h"
HANDLE32 COMCTL32_hHeap = (HANDLE32)NULL;
DWORD COMCTL32_dwProcessesAttached = 0;
/***********************************************************************
* ComCtl32LibMain [Internal] Initializes the internal 'COMCTL32.DLL'.
*
* PARAMS
* hinstDLL [I] handle to the 'dlls' instance
* fdwReason [I]
* lpvReserved [I] reserverd, must be NULL
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL32 WINAPI
ComCtl32LibMain (HINSTANCE32 hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
TRACE (commctrl, "%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
if (COMCTL32_dwProcessesAttached == 0) {
/* create private heap */
COMCTL32_hHeap = HeapCreate (0, 0x10000, 0);
TRACE (commctrl, "Heap created: 0x%x\n", COMCTL32_hHeap);
/* register all Win95 common control classes */
ANIMATE_Register ();
HEADER_Register ();
HOTKEY_Register ();
LISTVIEW_Register ();
PROGRESS_Register ();
STATUS_Register ();
TAB_Register ();
TOOLBAR_Register ();
TOOLTIPS_Register ();
TRACKBAR_Register ();
TREEVIEW_Register ();
UPDOWN_Register ();
}
COMCTL32_dwProcessesAttached++;
break;
case DLL_PROCESS_DETACH:
COMCTL32_dwProcessesAttached--;
if (COMCTL32_dwProcessesAttached == 0) {
/* unregister all common control classes */
ANIMATE_Unregister ();
COMBOEX_Unregister ();
HEADER_Unregister ();
HOTKEY_Unregister ();
IPADDRESS_Unregister ();
LISTVIEW_Unregister ();
NATIVEFONT_Unregister ();
PAGER_Unregister ();
PROGRESS_Unregister ();
REBAR_Unregister ();
STATUS_Unregister ();
TAB_Unregister ();
TOOLBAR_Unregister ();
TOOLTIPS_Unregister ();
TRACKBAR_Unregister ();
TREEVIEW_Unregister ();
UPDOWN_Unregister ();
/* destroy private heap */
HeapDestroy (COMCTL32_hHeap);
TRACE (commctrl, "Heap destroyed: 0x%x\n", COMCTL32_hHeap);
COMCTL32_hHeap = (HANDLE32)NULL;
}
break;
}
return TRUE;
}
/***********************************************************************
* MenuHelp [COMCTL32.2]
*
* PARAMS
* uMsg [I]
* wParam [I]
* lParam [I]
* hMainMenu [I] handle to the applications main menu
* hInst [I]
* hwndStatus [I] handle to the status bar window
* lpwIDs [I] pointer to an array of intergers (see NOTES)
*
* RETURNS
* No return value
*
* NOTES
* The official documentation is incomplete!
*/
VOID WINAPI
MenuHelp (UINT32 uMsg, WPARAM32 wParam, LPARAM lParam, HMENU32 hMainMenu,
HINSTANCE32 hInst, HWND32 hwndStatus, LPUINT32 lpwIDs)
{
UINT32 uMenuID = 0;
if (!IsWindow32 (hwndStatus))
return;
switch (uMsg) {
case WM_MENUSELECT:
TRACE (commctrl, "WM_MENUSELECT wParam=0x%X lParam=0x%lX\n",
wParam, lParam);
if ((HIWORD(wParam) == 0xFFFF) && (lParam == 0)) {
/* menu was closed */
TRACE (commctrl, "menu was closed!\n");
SendMessage32A (hwndStatus, SB_SIMPLE, FALSE, 0);
}
else {
/* menu item was selected */
if (HIWORD(wParam) & MF_POPUP)
uMenuID = (UINT32)*(lpwIDs+1);
else
uMenuID = (UINT32)LOWORD(wParam);
TRACE (commctrl, "uMenuID = %u\n", uMenuID);
if (uMenuID) {
CHAR szText[256];
if (!LoadString32A (hInst, uMenuID, szText, 256))
szText[0] = '\0';
SendMessage32A (hwndStatus, SB_SETTEXT32A,
255 | SBT_NOBORDERS, (LPARAM)szText);
SendMessage32A (hwndStatus, SB_SIMPLE, TRUE, 0);
}
}
break;
default:
FIXME (commctrl, "Invalid Message 0x%x!\n", uMsg);
break;
}
}
/***********************************************************************
* ShowHideMenuCtl [COMCTL32.3]
*
* Shows or hides controls and updates the corresponding menu item.
*
* PARAMS
* hwnd [I] handle to the client window.
* uFlags [I] menu command id.
* lpInfo [I] pointer to an array of integers. (See NOTES.)
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* NOTES
* The official documentation is incomplete! This has been fixed.
*
* lpInfo
* The array of integers contains pairs of values. BOTH values of
* the first pair must be the handles to application's main menu.
* Each subsequent pair consists of a menu id and control id.
*/
BOOL32 WINAPI
ShowHideMenuCtl (HWND32 hwnd, UINT32 uFlags, LPINT32 lpInfo)
{
LPINT32 lpMenuId;
TRACE (commctrl, "%x, %x, %p\n", hwnd, uFlags, lpInfo);
if (lpInfo == NULL)
return FALSE;
if (!(lpInfo[0]) || !(lpInfo[1]))
return FALSE;
/* search for control */
lpMenuId = &lpInfo[2];
while (*lpMenuId != uFlags)
lpMenuId += 2;
if (GetMenuState32 (lpInfo[1], uFlags, MF_BYCOMMAND) & MFS_CHECKED) {
/* uncheck menu item */
CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_UNCHECKED);
/* hide control */
lpMenuId++;
SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
SWP_HIDEWINDOW);
}
else {
/* check menu item */
CheckMenuItem32 (lpInfo[0], *lpMenuId, MF_BYCOMMAND | MF_CHECKED);
/* show control */
lpMenuId++;
SetWindowPos32 (GetDlgItem32 (hwnd, *lpMenuId), 0, 0, 0, 0, 0,
SWP_SHOWWINDOW);
}
return TRUE;
}
/***********************************************************************
* GetEffectiveClientRect [COMCTL32.4]
*
* PARAMS
* hwnd [I] handle to the client window.
* lpRect [O] pointer to the rectangle of the client window
* lpInfo [I] pointer to an array of integers
*
* RETURNS
* No return value.
*
* NOTES
* The official documentation is incomplete!
*/
VOID WINAPI
GetEffectiveClientRect (HWND32 hwnd, LPRECT32 lpRect, LPINT32 lpInfo)
{
RECT32 rcCtrl;
INT32 *lpRun;
HWND32 hwndCtrl;
TRACE (commctrl, "(0x%08lx 0x%08lx 0x%08lx)\n",
(DWORD)hwnd, (DWORD)lpRect, (DWORD)lpInfo);
GetClientRect32 (hwnd, lpRect);
lpRun = lpInfo;
do {
lpRun += 2;
if (*lpRun == 0)
return;
lpRun++;
hwndCtrl = GetDlgItem32 (hwnd, *lpRun);
if (GetWindowLong32A (hwndCtrl, GWL_STYLE) & WS_VISIBLE) {
TRACE (commctrl, "control id 0x%x\n", *lpRun);
GetWindowRect32 (hwndCtrl, &rcCtrl);
MapWindowPoints32 ((HWND32)0, hwnd, (LPPOINT32)&rcCtrl, 2);
SubtractRect32 (lpRect, lpRect, &rcCtrl);
}
lpRun++;
} while (*lpRun);
}
/***********************************************************************
* DrawStatusText32A [COMCTL32.5][COMCTL32.27]
*
* Draws text with borders, like in a status bar.
*
* PARAMS
* hdc [I] handle to the window's display context
* lprc [I] pointer to a rectangle
* text [I] pointer to the text
* style [I]
*
* RETURNS
* No return value.
*/
VOID WINAPI
DrawStatusText32A (HDC32 hdc, LPRECT32 lprc, LPCSTR text, UINT32 style)
{
RECT32 r = *lprc;
UINT32 border = BDR_SUNKENOUTER;
if (style == SBT_POPOUT)
border = BDR_RAISEDOUTER;
else if (style == SBT_NOBORDERS)
border = 0;
DrawEdge32 (hdc, &r, border, BF_RECT|BF_ADJUST|BF_MIDDLE);
/* now draw text */
if (text) {
int oldbkmode = SetBkMode32 (hdc, TRANSPARENT);
r.left += 3;
DrawText32A (hdc, text, lstrlen32A(text),
&r, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
if (oldbkmode != TRANSPARENT)
SetBkMode32(hdc, oldbkmode);
}
}
/***********************************************************************
* DrawStatusText32W [COMCTL32.28]
*
* Draws text with borders, like in a status bar.
*
* PARAMS
* hdc [I] handle to the window's display context
* lprc [I] pointer to a rectangle
* text [I] pointer to the text
* style [I]
*
* RETURNS
* No return value.
*/
VOID WINAPI
DrawStatusText32W (HDC32 hdc, LPRECT32 lprc, LPCWSTR text, UINT32 style)
{
LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, text);
DrawStatusText32A (hdc, lprc, p, style);
HeapFree (GetProcessHeap (), 0, p );
}
/***********************************************************************
* CreateStatusWindow32A [COMCTL32.6][COMCTL32.21] Creates a status bar
*
* PARAMS
* style [I]
* text [I]
* parent [I] handle to the parent window
* wid [I] control id of the status bar
*
* RETURNS
* Success: handle to the control
* Failure: 0
*/
HWND32 WINAPI
CreateStatusWindow32A (INT32 style, LPCSTR text, HWND32 parent, UINT32 wid)
{
return CreateWindow32A(STATUSCLASSNAME32A, text, style,
CW_USEDEFAULT32, CW_USEDEFAULT32,
CW_USEDEFAULT32, CW_USEDEFAULT32,
parent, wid, 0, 0);
}
/***********************************************************************
* CreateStatusWindow32W [COMCTL32.22] Creates a status bar control
*
* PARAMS
* style [I]
* text [I]
* parent [I] handle to the parent window
* wid [I] control id of the status bar
*
* RETURNS
* Success: handle to the control
* Failure: 0
*/
HWND32 WINAPI
CreateStatusWindow32W (INT32 style, LPCWSTR text, HWND32 parent, UINT32 wid)
{
return CreateWindow32W((LPCWSTR)STATUSCLASSNAME32W, text, style,
CW_USEDEFAULT32, CW_USEDEFAULT32,
CW_USEDEFAULT32, CW_USEDEFAULT32,
parent, wid, 0, 0);
}
/***********************************************************************
* CreateUpDownControl [COMCTL32.16] Creates an Up-Down control
*
* PARAMS
* style
* x
* y
* cx
* cy
* parent
* id
* inst
* buddy
* maxVal [I]
* minVal [I]
* curVal [I]
*
* RETURNS
* Success: handle to the control
* Failure: 0
*/
HWND32 WINAPI
CreateUpDownControl (DWORD style, INT32 x, INT32 y, INT32 cx, INT32 cy,
HWND32 parent, INT32 id, HINSTANCE32 inst,
HWND32 buddy, INT32 maxVal, INT32 minVal, INT32 curVal)
{
HWND32 hUD =
CreateWindow32A (UPDOWN_CLASS32A, 0, style, x, y, cx, cy,
parent, id, inst, 0);
if (hUD) {
SendMessage32A (hUD, UDM_SETBUDDY, buddy, 0);
SendMessage32A (hUD, UDM_SETRANGE, 0, MAKELONG(maxVal, minVal));
SendMessage32A (hUD, UDM_SETPOS, 0, MAKELONG(curVal, 0));
}
return hUD;
}
/***********************************************************************
* InitCommonControls [COMCTL32.17]
*
* Registers the common controls.
*
* PARAMS
* No parameters.
*
* RETURNS
* No return values.
*
* NOTES
* This function is just a dummy.
* The Win95 controls are registered at the DLL's initialization.
* To register other controls InitCommonControlsEx must be used.
*/
VOID WINAPI
InitCommonControls (VOID)
{
}
/***********************************************************************
* InitCommonControlsEx [COMCTL32.81]
*
* Registers the common controls.
*
* PARAMS
* lpInitCtrls [I] pointer to an INITCOMMONCONTROLS structure.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* NOTES
* Only the additinal common controls are registered by this function.
* The Win95 controls are registered at the DLL's initialization.
*/
BOOL32 WINAPI
InitCommonControlsEx (LPINITCOMMONCONTROLSEX lpInitCtrls)
{
INT32 cCount;
DWORD dwMask;
if (!lpInitCtrls)
return FALSE;
if (lpInitCtrls->dwSize != sizeof(INITCOMMONCONTROLSEX))
return FALSE;
TRACE(commctrl,"(0x%08lx)\n", lpInitCtrls->dwICC);
for (cCount = 0; cCount < 32; cCount++) {
dwMask = 1 << cCount;
if (!(lpInitCtrls->dwICC & dwMask))
continue;
switch (lpInitCtrls->dwICC & dwMask) {
/* dummy initialization */
case ICC_ANIMATE_CLASS:
case ICC_BAR_CLASSES:
case ICC_LISTVIEW_CLASSES:
case ICC_TREEVIEW_CLASSES:
case ICC_TAB_CLASSES:
case ICC_UPDOWN_CLASS:
case ICC_PROGRESS_CLASS:
case ICC_HOTKEY_CLASS:
break;
/* advanced classes - not included in Win95 */
case ICC_DATE_CLASSES:
FIXME (commctrl, "No month calendar class implemented!\n");
FIXME (commctrl, "No date and time picker class implemented!\n");
break;
case ICC_USEREX_CLASSES:
COMBOEX_Register ();
break;
case ICC_COOL_CLASSES:
REBAR_Register ();
break;
case ICC_INTERNET_CLASSES:
IPADDRESS_Register ();
break;
case ICC_PAGESCROLLER_CLASS:
PAGER_Register ();
break;
case ICC_NATIVEFNTCTL_CLASS:
NATIVEFONT_Register ();
break;
default:
FIXME (commctrl, "Unknown class! dwICC=0x%lX\n", dwMask);
break;
}
}
return TRUE;
}
/***********************************************************************
* CreateToolbarEx [COMCTL32.32] Creates a tool bar window
*
* PARAMS
* hwnd
* style
* wID
* nBitmaps
* hBMInst
* wBMID
* lpButtons
* iNumButtons
* dxButton
* dyButton
* dxBitmap
* dyBitmap
* uStructSize
*
* RETURNS
* Success: handle to the tool bar control
* Failure: 0
*/
HWND32 WINAPI
CreateToolbarEx (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
HINSTANCE32 hBMInst, UINT32 wBMID, LPCTBBUTTON lpButtons,
INT32 iNumButtons, INT32 dxButton, INT32 dyButton,
INT32 dxBitmap, INT32 dyBitmap, UINT32 uStructSize)
{
HWND32 hwndTB =
CreateWindowEx32A (0, TOOLBARCLASSNAME32A, "", style, 0, 0, 0, 0,
hwnd, (HMENU32)wID, 0, NULL);
if(hwndTB) {
TBADDBITMAP tbab;
SendMessage32A (hwndTB, TB_BUTTONSTRUCTSIZE,
(WPARAM32)uStructSize, 0);
/* set bitmap and button size */
if (hBMInst == HINST_COMMCTRL) {
if (wBMID & 1) {
SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
MAKELPARAM(26, 25));
SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
MAKELPARAM(33, 32));
}
else {
SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
MAKELPARAM(16, 15));
SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
MAKELPARAM(23, 22));
}
}
else {
SendMessage32A (hwndTB, TB_SETBITMAPSIZE, 0,
MAKELPARAM((WORD)dyBitmap, (WORD)dxBitmap));
SendMessage32A (hwndTB, TB_SETBUTTONSIZE, 0,
MAKELPARAM((WORD)dyButton, (WORD)dxButton));
}
/* add bitmaps */
tbab.hInst = hBMInst;
tbab.nID = wBMID;
SendMessage32A (hwndTB, TB_ADDBITMAP,
(WPARAM32)nBitmaps, (LPARAM)&tbab);
/* add buttons */
SendMessage32A (hwndTB, TB_ADDBUTTONS32A,
(WPARAM32)iNumButtons, (LPARAM)lpButtons);
}
return hwndTB;
}
/***********************************************************************
* CreateMappedBitmap [COMCTL32.8]
*
* PARAMS
* hInstance
* idBitmap
* wFlags
* lpColorMap
* iNumMaps
*
* RETURNS
* Success: bitmap handle
* Failure: 0
*/
HBITMAP32 WINAPI
CreateMappedBitmap (HINSTANCE32 hInstance, INT32 idBitmap, UINT32 wFlags,
LPCOLORMAP lpColorMap, INT32 iNumMaps)
{
HGLOBAL32 hglb;
HRSRC32 hRsrc;
LPBITMAPINFOHEADER lpBitmap, lpBitmapInfo;
UINT32 nSize, nColorTableSize;
DWORD *pColorTable;
INT32 iColor, i, iMaps, nWidth, nHeight;
HDC32 hdcScreen;
HBITMAP32 hbm;
LPCOLORMAP sysColorMap;
COLORMAP internalColorMap[4] =
{{0x000000, 0}, {0x808080, 0}, {0xC0C0C0, 0}, {0xFFFFFF, 0}};
/* initialize pointer to colortable and default color table */
if (lpColorMap) {
iMaps = iNumMaps;
sysColorMap = lpColorMap;
}
else {
internalColorMap[0].to = GetSysColor32 (COLOR_BTNTEXT);
internalColorMap[1].to = GetSysColor32 (COLOR_BTNSHADOW);
internalColorMap[2].to = GetSysColor32 (COLOR_BTNFACE);
internalColorMap[3].to = GetSysColor32 (COLOR_BTNHIGHLIGHT);
iMaps = 4;
sysColorMap = (LPCOLORMAP)internalColorMap;
}
hRsrc = FindResource32A (hInstance, (LPSTR)idBitmap, RT_BITMAP32A);
if (hRsrc == 0)
return 0;
hglb = LoadResource32 (hInstance, hRsrc);
if (hglb == 0)
return 0;
lpBitmap = (LPBITMAPINFOHEADER)LockResource32 (hglb);
if (lpBitmap == NULL)
return 0;
nColorTableSize = (1 << lpBitmap->biBitCount);
nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
lpBitmapInfo = (LPBITMAPINFOHEADER)GlobalAlloc32 (GMEM_FIXED, nSize);
if (lpBitmapInfo == NULL)
return 0;
RtlMoveMemory (lpBitmapInfo, lpBitmap, nSize);
pColorTable = (DWORD*)(((LPBYTE)lpBitmapInfo)+(UINT32)lpBitmapInfo->biSize);
for (iColor = 0; iColor < nColorTableSize; iColor++) {
for (i = 0; i < iMaps; i++) {
if (pColorTable[iColor] == sysColorMap[i].from) {
#if 0
if (wFlags & CBS_MASKED) {
if (sysColorMap[i].to != COLOR_BTNTEXT)
pColorTable[iColor] = RGB(255, 255, 255);
}
else
#endif
pColorTable[iColor] = sysColorMap[i].to;
break;
}
}
}
nWidth = (INT32)lpBitmapInfo->biWidth;
nHeight = (INT32)lpBitmapInfo->biHeight;
hdcScreen = GetDC32 ((HWND32)0);
hbm = CreateCompatibleBitmap32 (hdcScreen, nWidth, nHeight);
if (hbm) {
HDC32 hdcDst = CreateCompatibleDC32 (hdcScreen);
HBITMAP32 hbmOld = SelectObject32 (hdcDst, hbm);
LPBYTE lpBits = (LPBYTE)(lpBitmap + 1);
lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
StretchDIBits32 (hdcDst, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS,
SRCCOPY);
SelectObject32 (hdcDst, hbmOld);
DeleteDC32 (hdcDst);
}
ReleaseDC32 ((HWND32)0, hdcScreen);
GlobalFree32 ((HGLOBAL32)lpBitmapInfo);
FreeResource32 (hglb);
return hbm;
}
/***********************************************************************
* CreateToolbar [COMCTL32.7] Creates a tool bar control
*
* PARAMS
* hwnd
* style
* wID
* nBitmaps
* hBMInst
* wBMID
* lpButtons
* iNumButtons
*
* RETURNS
* Success: handle to the tool bar control
* Failure: 0
*
* NOTES
* Do not use this functions anymore. Use CreateToolbarEx instead.
*/
HWND32 WINAPI
CreateToolbar (HWND32 hwnd, DWORD style, UINT32 wID, INT32 nBitmaps,
HINSTANCE32 hBMInst, UINT32 wBMID,
LPCOLDTBBUTTON lpButtons,INT32 iNumButtons)
{
return CreateToolbarEx (hwnd, style | CCS_NODIVIDER, wID, nBitmaps,
hBMInst, wBMID, (LPCTBBUTTON)lpButtons,
iNumButtons, 0, 0, 0, 0, sizeof (OLDTBBUTTON));
}
/***********************************************************************
* DllGetVersion [COMCTL32.25]
*
* Retrieves version information of the 'COMCTL32.DLL'
*
* PARAMS
* pdvi [O] pointer to version information structure.
*
* RETURNS
* Success: S_OK
* Failure: E_INVALIDARG
*
* NOTES
* Returns version of a comctl32.dll from IE4.01 SP1.
*/
HRESULT WINAPI
COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
{
if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) {
WARN (commctrl, "wrong DLLVERSIONINFO size from app");
return E_INVALIDARG;
}
pdvi->dwMajorVersion = 4;
pdvi->dwMinorVersion = 72;
pdvi->dwBuildNumber = 3110;
pdvi->dwPlatformID = 1;
TRACE (commctrl, "%lu.%lu.%lu.%lu\n",
pdvi->dwMajorVersion, pdvi->dwMinorVersion,
pdvi->dwBuildNumber, pdvi->dwPlatformID);
return S_OK;
}
wine-981025/dlls/comctl32/header.c 100644 771 771 102207 6614330267 16502 0 ustar julliard julliard /*
* Header control
*
* Copyright 1998 Eric Kohl
*
* TODO:
* - Imagelist support (partially).
* - Callback items (under construction).
* - Order list support.
* - Control specific cursors (over dividers).
* - Hottrack support (partially).
* - Custom draw support (including Notifications).
* - Drag and Drop support (including Notifications).
* - Unicode support.
*
* FIXME:
* - Replace DrawText32A by DrawTextEx32A(...|DT_ENDELLIPSIS) in
* HEADER_DrawItem.
* - Little flaw when drawing a bitmap on the right side of the text.
*/
#include "windows.h"
#include "commctrl.h"
#include "header.h"
#include "win.h"
#include "debug.h"
#define __HDM_LAYOUT_HACK__
#define VERT_BORDER 4
#define DIVIDER_WIDTH 10
#define HEADER_GetInfoPtr(wndPtr) ((HEADER_INFO *)wndPtr->wExtra[0])
static INT32
HEADER_DrawItem (WND *wndPtr, HDC32 hdc, INT32 iItem, BOOL32 bHotTrack)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HEADER_ITEM *phdi = &infoPtr->items[iItem];
RECT32 r;
INT32 oldBkMode;
r = phdi->rect;
if (r.right - r.left == 0)
return phdi->rect.right;
if (wndPtr->dwStyle & HDS_BUTTONS) {
if (phdi->bDown) {
DrawEdge32 (hdc, &r, BDR_RAISEDOUTER,
BF_RECT | BF_FLAT | BF_MIDDLE | BF_ADJUST);
r.left += 2;
r.top += 2;
}
else
DrawEdge32 (hdc, &r, EDGE_RAISED,
BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
}
else
DrawEdge32 (hdc, &r, EDGE_ETCHED, BF_BOTTOM | BF_RIGHT | BF_ADJUST);
if (phdi->fmt & HDF_OWNERDRAW) {
DRAWITEMSTRUCT32 dis;
dis.CtlType = ODT_HEADER;
dis.CtlID = wndPtr->wIDmenu;
dis.itemID = iItem;
dis.itemAction = ODA_DRAWENTIRE;
dis.itemState = phdi->bDown ? ODS_SELECTED : 0;
dis.hwndItem = wndPtr->hwndSelf;
dis.hDC = hdc;
dis.rcItem = r;
dis.itemData = phdi->lParam;
SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_DRAWITEM,
(WPARAM32)wndPtr->wIDmenu, (LPARAM)&dis);
}
else {
UINT32 uTextJustify = DT_LEFT;
if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_CENTER)
uTextJustify = DT_CENTER;
else if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_RIGHT)
uTextJustify = DT_RIGHT;
if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) {
BITMAP32 bmp;
HDC32 hdcBitmap;
INT32 yD, yS, cx, cy, rx, ry;
GetObject32A (phdi->hbm, sizeof(BITMAP32), (LPVOID)&bmp);
ry = r.bottom - r.top;
rx = r.right - r.left;
if (ry >= bmp.bmHeight) {
cy = bmp.bmHeight;
yD = r.top + (ry - bmp.bmHeight) / 2;
yS = 0;
}
else {
cy = ry;
yD = r.top;
yS = (bmp.bmHeight - ry) / 2;
}
if (rx >= bmp.bmWidth + 6) {
cx = bmp.bmWidth;
}
else {
cx = rx - 6;
}
hdcBitmap = CreateCompatibleDC32 (hdc);
SelectObject32 (hdcBitmap, phdi->hbm);
BitBlt32 (hdc, r.left + 3, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
DeleteDC32 (hdcBitmap);
r.left += (bmp.bmWidth + 3);
}
if ((phdi->fmt & HDF_BITMAP_ON_RIGHT) && (phdi->hbm)) {
BITMAP32 bmp;
HDC32 hdcBitmap;
INT32 xD, yD, yS, cx, cy, rx, ry, tx;
RECT32 textRect;
GetObject32A (phdi->hbm, sizeof(BITMAP32), (LPVOID)&bmp);
textRect = r;
DrawText32A(hdc, phdi->pszText, lstrlen32A(phdi->pszText),
&textRect, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_CALCRECT);
tx = textRect.right - textRect.left;
ry = r.bottom - r.top;
rx = r.right - r.left;
if (ry >= bmp.bmHeight) {
cy = bmp.bmHeight;
yD = r.top + (ry - bmp.bmHeight) / 2;
yS = 0;
}
else {
cy = ry;
yD = r.top;
yS = (bmp.bmHeight - ry) / 2;
}
if (r.left + tx + bmp.bmWidth + 9 <= r.right) {
cx = bmp.bmWidth;
xD = r.left + tx + 6;
}
else {
if (rx >= bmp.bmWidth + 6) {
cx = bmp.bmWidth;
xD = r.right - bmp.bmWidth - 3;
r.right = xD - 3;
}
else {
cx = rx - 3;
xD = r.left;
r.right = r.left;
}
}
hdcBitmap = CreateCompatibleDC32 (hdc);
SelectObject32 (hdcBitmap, phdi->hbm);
BitBlt32 (hdc, xD, yD, cx, cy, hdcBitmap, 0, yS, SRCCOPY);
DeleteDC32 (hdcBitmap);
}
if (phdi->fmt & HDF_IMAGE) {
// ImageList_Draw (infoPtr->himl, phdi->iImage,...);
}
if ((phdi->fmt & HDF_STRING) && (phdi->pszText)) {
oldBkMode = SetBkMode32(hdc, TRANSPARENT);
r.left += 3;
r.right -= 3;
SetTextColor32 (hdc, bHotTrack ? COLOR_HIGHLIGHT : COLOR_BTNTEXT);
DrawText32A(hdc, phdi->pszText, lstrlen32A(phdi->pszText),
&r, uTextJustify|DT_VCENTER|DT_SINGLELINE);
if (oldBkMode != TRANSPARENT)
SetBkMode32(hdc, oldBkMode);
}
}
return phdi->rect.right;
}
static void
HEADER_Refresh (WND *wndPtr, HDC32 hdc)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HFONT32 hFont, hOldFont;
RECT32 rect;
HBRUSH32 hbrBk;
INT32 i, x;
/* get rect for the bar, adjusted for the border */
GetClientRect32 (wndPtr->hwndSelf, &rect);
hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
hOldFont = SelectObject32 (hdc, hFont);
/* draw Background */
hbrBk = GetSysColorBrush32(COLOR_3DFACE);
FillRect32(hdc, &rect, hbrBk);
x = rect.left;
for (i = 0; i < infoPtr->uNumItem; i++) {
x = HEADER_DrawItem (wndPtr, hdc, i, FALSE);
}
if ((x <= rect.right) && (infoPtr->uNumItem > 0)) {
rect.left = x;
if (wndPtr->dwStyle & HDS_BUTTONS)
DrawEdge32 (hdc, &rect, EDGE_RAISED, BF_TOP|BF_LEFT|BF_BOTTOM|BF_SOFT);
else
DrawEdge32 (hdc, &rect, EDGE_ETCHED, BF_BOTTOM);
}
SelectObject32 (hdc, hOldFont);
}
static void
HEADER_RefreshItem (WND *wndPtr, HDC32 hdc, INT32 iItem)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HFONT32 hFont, hOldFont;
hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
hOldFont = SelectObject32 (hdc, hFont);
HEADER_DrawItem (wndPtr, hdc, iItem, FALSE);
SelectObject32 (hdc, hOldFont);
}
static void
HEADER_SetItemBounds (WND *wndPtr)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HEADER_ITEM *phdi;
RECT32 rect;
int i, x;
if (infoPtr->uNumItem == 0)
return;
GetClientRect32 (wndPtr->hwndSelf, &rect);
x = rect.left;
for (i = 0; i < infoPtr->uNumItem; i++) {
phdi = &infoPtr->items[i];
phdi->rect.top = rect.top;
phdi->rect.bottom = rect.bottom;
phdi->rect.left = x;
phdi->rect.right = phdi->rect.left + phdi->cxy;
x = phdi->rect.right;
}
}
static void
HEADER_ForceItemBounds (WND *wndPtr, INT32 cy)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HEADER_ITEM *phdi;
int i, x;
if (infoPtr->uNumItem == 0)
return;
x = 0;
for (i = 0; i < infoPtr->uNumItem; i++) {
phdi = &infoPtr->items[i];
phdi->rect.top = 0;
phdi->rect.bottom = cy;
phdi->rect.left = x;
phdi->rect.right = phdi->rect.left + phdi->cxy;
x = phdi->rect.right;
}
}
static void
HEADER_InternalHitTest (WND *wndPtr, LPPOINT32 lpPt, UINT32 *pFlags, INT32 *pItem)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
RECT32 rect, rcTest;
INT32 iCount, width;
BOOL32 bNoWidth;
GetClientRect32 (wndPtr->hwndSelf, &rect);
*pFlags = 0;
bNoWidth = FALSE;
if (PtInRect32 (&rect, *lpPt))
{
if (infoPtr->uNumItem == 0) {
*pFlags |= HHT_NOWHERE;
*pItem = 1;
TRACE (header, "NOWHERE\n");
return;
}
else {
/* somewhere inside */
for (iCount = 0; iCount < infoPtr->uNumItem; iCount++) {
rect = infoPtr->items[iCount].rect;
width = rect.right - rect.left;
if (width == 0) {
bNoWidth = TRUE;
continue;
}
if (PtInRect32 (&rect, *lpPt)) {
if (width <= 2 * DIVIDER_WIDTH) {
*pFlags |= HHT_ONHEADER;
*pItem = iCount;
TRACE (header, "ON HEADER %d\n", iCount);
return;
}
if (iCount > 0) {
rcTest = rect;
rcTest.right = rcTest.left + DIVIDER_WIDTH;
if (PtInRect32 (&rcTest, *lpPt)) {
if (bNoWidth) {
*pFlags |= HHT_ONDIVOPEN;
*pItem = iCount - 1;
TRACE (header, "ON DIVOPEN %d\n", *pItem);
return;
}
else {
*pFlags |= HHT_ONDIVIDER;
*pItem = iCount - 1;
TRACE (header, "ON DIVIDER %d\n", *pItem);
return;
}
}
}
rcTest = rect;
rcTest.left = rcTest.right - DIVIDER_WIDTH;
if (PtInRect32 (&rcTest, *lpPt)) {
*pFlags |= HHT_ONDIVIDER;
*pItem = iCount;
TRACE (header, "ON DIVIDER %d\n", *pItem);
return;
}
*pFlags |= HHT_ONHEADER;
*pItem = iCount;
TRACE (header, "ON HEADER %d\n", iCount);
return;
}
}
/* check for last divider part (on nowhere) */
rect = infoPtr->items[infoPtr->uNumItem-1].rect;
rect.left = rect.right;
rect.right += DIVIDER_WIDTH;
if (PtInRect32 (&rect, *lpPt)) {
if (bNoWidth) {
*pFlags |= HHT_ONDIVOPEN;
*pItem = infoPtr->uNumItem - 1;
TRACE (header, "ON DIVOPEN %d\n", *pItem);
return;
}
else {
*pFlags |= HHT_ONDIVIDER;
*pItem = infoPtr->uNumItem-1;
TRACE (header, "ON DIVIDER %d\n", *pItem);
return;
}
}
*pFlags |= HHT_NOWHERE;
*pItem = 1;
TRACE (header, "NOWHERE\n");
return;
}
}
else {
if (lpPt->x < rect.left) {
TRACE (header, "TO LEFT\n");
*pFlags |= HHT_TOLEFT;
}
else if (lpPt->x > rect.right) {
TRACE (header, "TO LEFT\n");
*pFlags |= HHT_TORIGHT;
}
if (lpPt->y < rect.top) {
TRACE (header, "ABOVE\n");
*pFlags |= HHT_ABOVE;
}
else if (lpPt->y > rect.bottom) {
TRACE (header, "BELOW\n");
*pFlags |= HHT_BELOW;
}
}
*pItem = 1;
TRACE (header, "flags=0x%X\n", *pFlags);
return;
}
static void
HEADER_DrawTrackLine (WND *wndPtr, HDC32 hdc, INT32 x)
{
RECT32 rect;
HPEN32 hOldPen;
INT32 oldRop;
GetClientRect32 (wndPtr->hwndSelf, &rect);
hOldPen = SelectObject32 (hdc, GetStockObject32 (BLACK_PEN));
oldRop = SetROP232 (hdc, R2_XORPEN);
MoveToEx32 (hdc, x, rect.top, NULL);
LineTo32 (hdc, x, rect.bottom);
SetROP232 (hdc, oldRop);
SelectObject32 (hdc, hOldPen);
}
static BOOL32
HEADER_SendSimpleNotify (WND *wndPtr, UINT32 code)
{
NMHDR nmhdr;
nmhdr.hwndFrom = wndPtr->hwndSelf;
nmhdr.idFrom = wndPtr->wIDmenu;
nmhdr.code = code;
return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
(WPARAM32)nmhdr.idFrom, (LPARAM)&nmhdr);
}
static BOOL32
HEADER_SendHeaderNotify (WND *wndPtr, UINT32 code, INT32 iItem)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
NMHEADER32A nmhdr;
HDITEM32A nmitem;
nmhdr.hdr.hwndFrom = wndPtr->hwndSelf;
nmhdr.hdr.idFrom = wndPtr->wIDmenu;
nmhdr.hdr.code = code;
nmhdr.iItem = iItem;
nmhdr.iButton = 0;
nmhdr.pitem = &nmitem;
nmitem.mask = 0;
nmitem.cxy = infoPtr->items[iItem].cxy;
nmitem.hbm = infoPtr->items[iItem].hbm;
nmitem.pszText = NULL;
nmitem.cchTextMax = 0;
// nmitem.pszText = infoPtr->items[iItem].pszText;
// nmitem.cchTextMax = infoPtr->items[iItem].cchTextMax;
nmitem.fmt = infoPtr->items[iItem].fmt;
nmitem.lParam = infoPtr->items[iItem].lParam;
nmitem.iOrder = infoPtr->items[iItem].iOrder;
nmitem.iImage = infoPtr->items[iItem].iImage;
return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
(WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmhdr);
}
static BOOL32
HEADER_SendClickNotify (WND *wndPtr, UINT32 code, INT32 iItem)
{
NMHEADER32A nmhdr;
nmhdr.hdr.hwndFrom = wndPtr->hwndSelf;
nmhdr.hdr.idFrom = wndPtr->wIDmenu;
nmhdr.hdr.code = code;
nmhdr.iItem = iItem;
nmhdr.iButton = 0;
nmhdr.pitem = NULL;
return (BOOL32)SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
(WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmhdr);
}
static LRESULT
HEADER_CreateDragImage (WND *wndPtr, WPARAM32 wParam)
{
FIXME (header, "empty stub!\n");
return 0;
}
static LRESULT
HEADER_DeleteItem (WND *wndPtr, WPARAM32 wParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
INT32 iItem = (INT32)wParam;
HDC32 hdc;
TRACE(header, "[iItem=%d]\n", iItem);
if ((iItem < 0) || (iItem >= (INT32)infoPtr->uNumItem))
return FALSE;
if (infoPtr->uNumItem == 1) {
TRACE(header, "Simple delete!\n");
if (infoPtr->items[0].pszText)
COMCTL32_Free (infoPtr->items[0].pszText);
COMCTL32_Free (infoPtr->items);
infoPtr->items = 0;
infoPtr->uNumItem = 0;
}
else {
HEADER_ITEM *oldItems = infoPtr->items;
TRACE(header, "Complex delete! [iItem=%d]\n", iItem);
if (infoPtr->items[iItem].pszText)
COMCTL32_Free (infoPtr->items[iItem].pszText);
infoPtr->uNumItem--;
infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
/* pre delete copy */
if (iItem > 0) {
memcpy (&infoPtr->items[0], &oldItems[0],
iItem * sizeof(HEADER_ITEM));
}
/* post delete copy */
if (iItem < infoPtr->uNumItem) {
memcpy (&infoPtr->items[iItem], &oldItems[iItem+1],
(infoPtr->uNumItem - iItem) * sizeof(HEADER_ITEM));
}
COMCTL32_Free (oldItems);
}
HEADER_SetItemBounds (wndPtr);
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_Refresh (wndPtr, hdc);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
return TRUE;
}
static LRESULT
HEADER_GetImageList (WND *wndPtr)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
return (LRESULT)infoPtr->himl;
}
static LRESULT
HEADER_GetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HDITEM32A *phdi = (HDITEM32A*)lParam;
INT32 nItem = (INT32)wParam;
HEADER_ITEM *lpItem;
if (!phdi)
return FALSE;
if ((nItem < 0) || (nItem >= (INT32)infoPtr->uNumItem))
return FALSE;
TRACE (header, "[nItem=%d]\n", nItem);
if (phdi->mask == 0)
return TRUE;
lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
if (phdi->mask & HDI_BITMAP)
phdi->hbm = lpItem->hbm;
if (phdi->mask & HDI_FORMAT)
phdi->fmt = lpItem->fmt;
if (phdi->mask & HDI_WIDTH)
phdi->cxy = lpItem->cxy;
if (phdi->mask & HDI_LPARAM)
phdi->lParam = lpItem->lParam;
if (phdi->mask & HDI_TEXT) {
if (lpItem->pszText != LPSTR_TEXTCALLBACK32A)
lstrcpyn32A (phdi->pszText, lpItem->pszText, phdi->cchTextMax);
else
phdi->pszText = LPSTR_TEXTCALLBACK32A;
}
if (phdi->mask & HDI_IMAGE)
phdi->iImage = lpItem->iImage;
if (phdi->mask & HDI_ORDER)
phdi->iOrder = lpItem->iOrder;
return TRUE;
}
static LRESULT
HEADER_GetItemCount (WND *wndPtr)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
return (infoPtr->uNumItem);
}
static LRESULT
HEADER_GetItemRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
INT32 iItem = (INT32)wParam;
LPRECT32 lpRect = (LPRECT32)lParam;
if ((iItem < 0) || (iItem >= (INT32)infoPtr->uNumItem))
return FALSE;
lpRect->left = infoPtr->items[iItem].rect.left;
lpRect->right = infoPtr->items[iItem].rect.right;
lpRect->top = infoPtr->items[iItem].rect.top;
lpRect->bottom = infoPtr->items[iItem].rect.bottom;
return TRUE;
}
static LRESULT
HEADER_HitTest (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
LPHDHITTESTINFO phti = (LPHDHITTESTINFO)lParam;
HEADER_InternalHitTest (wndPtr, &phti->pt, &phti->flags, &phti->iItem);
return phti->flags;
}
static LRESULT
HEADER_InsertItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HDITEM32A *phdi = (HDITEM32A*)lParam;
INT32 nItem = (INT32)wParam;
HEADER_ITEM *lpItem;
HDC32 hdc;
INT32 len;
if ((phdi == NULL) || (nItem < 0))
return -1;
if (nItem > infoPtr->uNumItem)
nItem = infoPtr->uNumItem;
if (infoPtr->uNumItem == 0) {
infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM));
infoPtr->uNumItem++;
}
else {
HEADER_ITEM *oldItems = infoPtr->items;
infoPtr->uNumItem++;
infoPtr->items = COMCTL32_Alloc (sizeof (HEADER_ITEM) * infoPtr->uNumItem);
/* pre insert copy */
if (nItem > 0) {
memcpy (&infoPtr->items[0], &oldItems[0],
nItem * sizeof(HEADER_ITEM));
}
/* post insert copy */
if (nItem < infoPtr->uNumItem - 1) {
memcpy (&infoPtr->items[nItem+1], &oldItems[nItem],
(infoPtr->uNumItem - nItem) * sizeof(HEADER_ITEM));
}
COMCTL32_Free (oldItems);
}
lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
lpItem->bDown = FALSE;
if (phdi->mask & HDI_WIDTH)
lpItem->cxy = phdi->cxy;
if (phdi->mask & HDI_TEXT) {
if (phdi->pszText != LPSTR_TEXTCALLBACK32A) {
len = lstrlen32A (phdi->pszText);
lpItem->pszText = COMCTL32_Alloc (len+1);
lstrcpy32A (lpItem->pszText, phdi->pszText);
}
else
lpItem->pszText = LPSTR_TEXTCALLBACK32A;
}
if (phdi->mask & HDI_FORMAT)
lpItem->fmt = phdi->fmt;
if (lpItem->fmt == 0)
lpItem->fmt = HDF_LEFT;
if (phdi->mask & HDI_BITMAP)
lpItem->hbm = phdi->hbm;
if (phdi->mask & HDI_LPARAM)
lpItem->lParam = phdi->lParam;
if (phdi->mask & HDI_IMAGE)
lpItem->iImage = phdi->iImage;
if (phdi->mask & HDI_ORDER)
lpItem->iOrder = phdi->iOrder;
HEADER_SetItemBounds (wndPtr);
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_Refresh (wndPtr, hdc);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
return nItem;
}
static LRESULT
HEADER_Layout (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
LPHDLAYOUT lpLayout = (LPHDLAYOUT)lParam;
lpLayout->pwpos->hwnd = wndPtr->hwndSelf;
lpLayout->pwpos->hwndInsertAfter = 0;
lpLayout->pwpos->x = lpLayout->prc->left;
lpLayout->pwpos->y = lpLayout->prc->top;
lpLayout->pwpos->cx = lpLayout->prc->right - lpLayout->prc->left;
if (wndPtr->dwStyle & HDS_HIDDEN)
lpLayout->pwpos->cy = 0;
else
lpLayout->pwpos->cy = infoPtr->nHeight;
lpLayout->pwpos->flags = SWP_NOZORDER;
TRACE (header, "Layout x=%d y=%d cx=%d cy=%d\n",
lpLayout->pwpos->x, lpLayout->pwpos->y,
lpLayout->pwpos->cx, lpLayout->pwpos->cy);
HEADER_ForceItemBounds (wndPtr, lpLayout->pwpos->cy);
/* hack */
#ifdef __HDM_LAYOUT_HACK__
MoveWindow32 (lpLayout->pwpos->hwnd, lpLayout->pwpos->x, lpLayout->pwpos->y,
lpLayout->pwpos->cx, lpLayout->pwpos->cy, TRUE);
#endif
return TRUE;
}
static LRESULT
HEADER_SetImageList (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HIMAGELIST himlOld;
himlOld = infoPtr->himl;
infoPtr->himl = (HIMAGELIST)lParam;
/* FIXME: Refresh needed??? */
return (LRESULT)himlOld;
}
static LRESULT
HEADER_SetItem32A (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HDITEM32A *phdi = (HDITEM32A*)lParam;
INT32 nItem = (INT32)wParam;
HEADER_ITEM *lpItem;
HDC32 hdc;
if (phdi == NULL)
return FALSE;
if ((nItem < 0) || (nItem >= (INT32)infoPtr->uNumItem))
return FALSE;
TRACE (header, "[nItem=%d]\n", nItem);
if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, nItem))
return FALSE;
lpItem = (HEADER_ITEM*)&infoPtr->items[nItem];
if (phdi->mask & HDI_BITMAP)
lpItem->hbm = phdi->hbm;
if (phdi->mask & HDI_FORMAT)
lpItem->fmt = phdi->fmt;
if (phdi->mask & HDI_LPARAM)
lpItem->lParam = phdi->lParam;
if (phdi->mask & HDI_TEXT) {
if (phdi->pszText != LPSTR_TEXTCALLBACK32A) {
INT32 len = lstrlen32A (phdi->pszText);
if (lpItem->pszText)
COMCTL32_Free (lpItem->pszText);
lpItem->pszText = COMCTL32_Alloc (len+1);
lstrcpy32A (lpItem->pszText, phdi->pszText);
}
else
lpItem->pszText = LPSTR_TEXTCALLBACK32A;
}
if (phdi->mask & HDI_WIDTH)
lpItem->cxy = phdi->cxy;
if (phdi->mask & HDI_IMAGE)
lpItem->iImage = phdi->iImage;
if (phdi->mask & HDI_ORDER)
lpItem->iOrder = phdi->iOrder;
HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A, nItem);
HEADER_SetItemBounds (wndPtr);
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_Refresh (wndPtr, hdc);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
return TRUE;
}
static LRESULT
HEADER_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr;
TEXTMETRIC32A tm;
HFONT32 hOldFont;
HDC32 hdc;
infoPtr = (HEADER_INFO *)COMCTL32_Alloc (sizeof(HEADER_INFO));
wndPtr->wExtra[0] = (DWORD)infoPtr;
infoPtr->uNumItem = 0;
infoPtr->nHeight = 20;
infoPtr->hFont = 0;
infoPtr->items = 0;
infoPtr->hcurArrow = LoadCursor32A (0, IDC_ARROW32A);
infoPtr->hcurDivider = LoadCursor32A (0, IDC_SIZEWE32A);
infoPtr->hcurDivopen = LoadCursor32A (0, IDC_SIZENS32A);
infoPtr->bPressed = FALSE;
infoPtr->bTracking = FALSE;
infoPtr->iMoveItem = 0;
infoPtr->himl = 0;
infoPtr->iHotItem = -1;
hdc = GetDC32 (0);
hOldFont = SelectObject32 (hdc, GetStockObject32 (SYSTEM_FONT));
GetTextMetrics32A (hdc, &tm);
infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
SelectObject32 (hdc, hOldFont);
ReleaseDC32 (0, hdc);
return 0;
}
static LRESULT
HEADER_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
HEADER_ITEM *lpItem;
INT32 nItem;
if (infoPtr->items) {
lpItem = (HEADER_ITEM*)infoPtr->items;
for (nItem = 0; nItem < infoPtr->uNumItem; nItem++, lpItem++) {
if ((lpItem->pszText) && (lpItem->pszText != LPSTR_TEXTCALLBACK32A))
COMCTL32_Free (lpItem->pszText);
}
COMCTL32_Free (infoPtr->items);
}
if (infoPtr->himl)
ImageList_Destroy (infoPtr->himl);
COMCTL32_Free (infoPtr);
return 0;
}
static __inline__ LRESULT
HEADER_GetFont (WND *wndPtr)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
return (LRESULT)infoPtr->hFont;
}
static LRESULT
HEADER_LButtonDblClk (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
POINT32 pt;
UINT32 flags;
INT32 nItem;
pt.x = (INT32)LOWORD(lParam);
pt.y = (INT32)HIWORD(lParam);
HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
if ((wndPtr->dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER))
HEADER_SendHeaderNotify (wndPtr, HDN_ITEMDBLCLICK32A, nItem);
else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN))
HEADER_SendHeaderNotify (wndPtr, HDN_DIVIDERDBLCLICK32A, nItem);
return 0;
}
static LRESULT
HEADER_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
POINT32 pt;
UINT32 flags;
INT32 nItem;
HDC32 hdc;
pt.x = (INT32)LOWORD(lParam);
pt.y = (INT32)HIWORD(lParam);
HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
if ((wndPtr->dwStyle & HDS_BUTTONS) && (flags == HHT_ONHEADER)) {
SetCapture32 (wndPtr->hwndSelf);
infoPtr->bCaptured = TRUE;
infoPtr->bPressed = TRUE;
infoPtr->iMoveItem = nItem;
infoPtr->items[nItem].bDown = TRUE;
/* Send WM_CUSTOMDRAW */
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_RefreshItem (wndPtr, hdc, nItem);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
TRACE (header, "Pressed item %d!\n", nItem);
}
else if ((flags == HHT_ONDIVIDER) || (flags == HHT_ONDIVOPEN)) {
if (!(HEADER_SendHeaderNotify (wndPtr, HDN_BEGINTRACK32A, nItem))) {
SetCapture32 (wndPtr->hwndSelf);
infoPtr->bCaptured = TRUE;
infoPtr->bTracking = TRUE;
infoPtr->iMoveItem = nItem;
infoPtr->nOldWidth = infoPtr->items[nItem].cxy;
infoPtr->xTrackOffset = infoPtr->items[nItem].rect.right - pt.x;
if (!(wndPtr->dwStyle & HDS_FULLDRAG)) {
infoPtr->xOldTrack = infoPtr->items[nItem].rect.right;
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
}
TRACE (header, "Begin tracking item %d!\n", nItem);
}
}
return 0;
}
static LRESULT
HEADER_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
POINT32 pt;
UINT32 flags;
INT32 nItem, nWidth;
HDC32 hdc;
pt.x = (INT32)LOWORD(lParam);
pt.y = (INT32)HIWORD(lParam);
HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
if (infoPtr->bPressed) {
if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER)) {
infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_RefreshItem (wndPtr, hdc, infoPtr->iMoveItem);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
HEADER_SendClickNotify (wndPtr, HDN_ITEMCLICK32A, infoPtr->iMoveItem);
}
TRACE (header, "Released item %d!\n", infoPtr->iMoveItem);
infoPtr->bPressed = FALSE;
}
else if (infoPtr->bTracking) {
TRACE (header, "End tracking item %d!\n", infoPtr->iMoveItem);
infoPtr->bTracking = FALSE;
HEADER_SendHeaderNotify (wndPtr, HDN_ENDTRACK32A, infoPtr->iMoveItem);
if (!(wndPtr->dwStyle & HDS_FULLDRAG)) {
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, infoPtr->iMoveItem))
infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
else {
nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
if (nWidth < 0)
nWidth = 0;
infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A, infoPtr->iMoveItem);
}
HEADER_SetItemBounds (wndPtr);
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_Refresh (wndPtr, hdc);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
}
}
if (infoPtr->bCaptured) {
infoPtr->bCaptured = FALSE;
ReleaseCapture ();
HEADER_SendSimpleNotify (wndPtr, NM_RELEASEDCAPTURE);
}
return 0;
}
static LRESULT
HEADER_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
POINT32 pt;
UINT32 flags;
INT32 nItem, nWidth;
HDC32 hdc;
pt.x = (INT32)LOWORD(lParam);
pt.y = (INT32)HIWORD(lParam);
HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
if ((wndPtr->dwStyle & HDS_BUTTONS) && (wndPtr->dwStyle & HDS_HOTTRACK)) {
if (flags & (HHT_ONHEADER | HHT_ONDIVIDER | HHT_ONDIVOPEN))
infoPtr->iHotItem = nItem;
else
infoPtr->iHotItem = -1;
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_Refresh (wndPtr, hdc);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
}
if (infoPtr->bCaptured) {
if (infoPtr->bPressed) {
if ((nItem == infoPtr->iMoveItem) && (flags == HHT_ONHEADER))
infoPtr->items[infoPtr->iMoveItem].bDown = TRUE;
else
infoPtr->items[infoPtr->iMoveItem].bDown = FALSE;
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_RefreshItem (wndPtr, hdc, infoPtr->iMoveItem);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
TRACE (header, "Moving pressed item %d!\n", infoPtr->iMoveItem);
}
else if (infoPtr->bTracking) {
if (wndPtr->dwStyle & HDS_FULLDRAG) {
if (HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGING32A, infoPtr->iMoveItem))
infoPtr->items[infoPtr->iMoveItem].cxy = infoPtr->nOldWidth;
else {
nWidth = pt.x - infoPtr->items[infoPtr->iMoveItem].rect.left + infoPtr->xTrackOffset;
if (nWidth < 0)
nWidth = 0;
infoPtr->items[infoPtr->iMoveItem].cxy = nWidth;
HEADER_SendHeaderNotify (wndPtr, HDN_ITEMCHANGED32A,
infoPtr->iMoveItem);
}
HEADER_SetItemBounds (wndPtr);
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_Refresh (wndPtr, hdc);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
}
else {
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
infoPtr->xOldTrack = pt.x + infoPtr->xTrackOffset;
if (infoPtr->xOldTrack < infoPtr->items[infoPtr->iMoveItem].rect.left)
infoPtr->xOldTrack = infoPtr->items[infoPtr->iMoveItem].rect.left;
infoPtr->items[infoPtr->iMoveItem].cxy =
infoPtr->xOldTrack - infoPtr->items[infoPtr->iMoveItem].rect.left;
HEADER_DrawTrackLine (wndPtr, hdc, infoPtr->xOldTrack);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
}
HEADER_SendHeaderNotify (wndPtr, HDN_TRACK32A, infoPtr->iMoveItem);
TRACE (header, "Tracking item %d!\n", infoPtr->iMoveItem);
}
}
if ((wndPtr->dwStyle & HDS_BUTTONS) && (wndPtr->dwStyle & HDS_HOTTRACK)) {
FIXME (header, "hot track support!\n");
}
return 0;
}
static LRESULT
HEADER_Paint (WND *wndPtr, WPARAM32 wParam)
{
HDC32 hdc;
PAINTSTRUCT32 ps;
hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
HEADER_Refresh (wndPtr, hdc);
if(!wParam)
EndPaint32 (wndPtr->hwndSelf, &ps);
return 0;
}
static LRESULT
HEADER_RButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
return HEADER_SendSimpleNotify (wndPtr, NM_RCLICK);
}
static LRESULT
HEADER_SetCursor (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
POINT32 pt;
UINT32 flags;
INT32 nItem;
TRACE (header, "code=0x%X id=0x%X\n", LOWORD(lParam), HIWORD(lParam));
GetCursorPos32 (&pt);
ScreenToClient32 (wndPtr->hwndSelf, &pt);
HEADER_InternalHitTest (wndPtr, &pt, &flags, &nItem);
if (flags == HHT_ONDIVIDER)
SetCursor32 (infoPtr->hcurDivider);
else if (flags == HHT_ONDIVOPEN)
SetCursor32 (infoPtr->hcurDivopen);
else
SetCursor32 (infoPtr->hcurArrow);
return 0;
}
static LRESULT
HEADER_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HEADER_INFO *infoPtr = HEADER_GetInfoPtr(wndPtr);
TEXTMETRIC32A tm;
HFONT32 hFont, hOldFont;
HDC32 hdc;
infoPtr->hFont = (HFONT32)wParam;
hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject32 (SYSTEM_FONT);
hdc = GetDC32 (0);
hOldFont = SelectObject32 (hdc, hFont);
GetTextMetrics32A (hdc, &tm);
infoPtr->nHeight = tm.tmHeight + VERT_BORDER;
SelectObject32 (hdc, hOldFont);
ReleaseDC32 (0, hdc);
if (lParam) {
HEADER_ForceItemBounds (wndPtr, infoPtr->nHeight);
hdc = GetDC32 (wndPtr->hwndSelf);
HEADER_Refresh (wndPtr, hdc);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
}
return 0;
}
LRESULT WINAPI
HEADER_WindowProc (HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
switch (msg) {
case HDM_CREATEDRAGIMAGE:
return HEADER_CreateDragImage (wndPtr, wParam);
case HDM_DELETEITEM:
return HEADER_DeleteItem (wndPtr, wParam);
case HDM_GETIMAGELIST:
return HEADER_GetImageList (wndPtr);
case HDM_GETITEM32A:
return HEADER_GetItem32A (wndPtr, wParam, lParam);
// case HDM_GETITEM32W:
case HDM_GETITEMCOUNT:
return HEADER_GetItemCount (wndPtr);
case HDM_GETITEMRECT:
return HEADER_GetItemRect (wndPtr, wParam, lParam);
// case HDM_GETORDERARRAY:
// case HDM_GETUNICODEFORMAT:
case HDM_HITTEST:
return HEADER_HitTest (wndPtr, wParam, lParam);
case HDM_INSERTITEM32A:
return HEADER_InsertItem32A (wndPtr, wParam, lParam);
// case HDM_INSERTITEM32W:
case HDM_LAYOUT:
return HEADER_Layout (wndPtr, wParam, lParam);
case HDM_SETIMAGELIST:
return HEADER_SetImageList (wndPtr, wParam, lParam);
case HDM_SETITEM32A:
return HEADER_SetItem32A (wndPtr, wParam, lParam);
// case HDM_SETITEM32W:
// case HDM_SETORDERARRAY:
// case HDM_SETUNICODEFORMAT:
case WM_CREATE:
return HEADER_Create (wndPtr, wParam, lParam);
case WM_DESTROY:
return HEADER_Destroy (wndPtr, wParam, lParam);
case WM_ERASEBKGND:
return 1;
case WM_GETDLGCODE:
return DLGC_WANTTAB | DLGC_WANTARROWS;
case WM_GETFONT:
return HEADER_GetFont (wndPtr);
case WM_LBUTTONDBLCLK:
return HEADER_LButtonDblClk (wndPtr, wParam, lParam);
case WM_LBUTTONDOWN:
return HEADER_LButtonDown (wndPtr, wParam, lParam);
case WM_LBUTTONUP:
return HEADER_LButtonUp (wndPtr, wParam, lParam);
case WM_MOUSEMOVE:
return HEADER_MouseMove (wndPtr, wParam, lParam);
case WM_PAINT:
return HEADER_Paint (wndPtr, wParam);
case WM_RBUTTONUP:
return HEADER_RButtonUp (wndPtr, wParam, lParam);
case WM_SETCURSOR:
return HEADER_SetCursor (wndPtr, wParam, lParam);
case WM_SETFONT:
return HEADER_SetFont (wndPtr, wParam, lParam);
default:
if (msg >= WM_USER)
ERR (header, "unknown msg %04x wp=%04x lp=%08lx\n",
msg, wParam, lParam );
return DefWindowProc32A (hwnd, msg, wParam, lParam);
}
return 0;
}
VOID
HEADER_Register (VOID)
{
WNDCLASS32A wndClass;
if (GlobalFindAtom32A (WC_HEADER32A)) return;
ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
wndClass.lpfnWndProc = (WNDPROC32)HEADER_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(HEADER_INFO *);
wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
wndClass.lpszClassName = WC_HEADER32A;
RegisterClass32A (&wndClass);
}
VOID
HEADER_Unregister (VOID)
{
if (GlobalFindAtom32A (WC_HEADER32A))
UnregisterClass32A (WC_HEADER32A, (HINSTANCE32)NULL);
}
wine-981025/dlls/comctl32/hotkey.c 100644 771 771 16073 6614330267 16542 0 ustar julliard julliard /*
* Hotkey control
*
* Copyright 1998 Eric Kohl
*
* NOTES
* Development in progress. An author is needed! Any volunteers?
* I will only improve this control once in a while.
* Eric <ekohl@abo.rhein-zeitung.de>
*
* TODO:
* - Some messages.
* - Display code.
*/
#include "windows.h"
#include "commctrl.h"
#include "hotkey.h"
#include "win.h"
#include "debug.h"
#define HOTKEY_GetInfoPtr(wndPtr) ((HOTKEY_INFO *)wndPtr->wExtra[0])
// << HOTHEY_GetHotKey >>
// << HOTHEY_SetHotKey >>
// << HOTHEY_SetRules >>
// << HOTKEY_Char >>
static LRESULT
HOTKEY_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr;
TEXTMETRIC32A tm;
HDC32 hdc;
/* allocate memory for info structure */
infoPtr = (HOTKEY_INFO *)COMCTL32_Alloc (sizeof(HOTKEY_INFO));
wndPtr->wExtra[0] = (DWORD)infoPtr;
if (infoPtr == NULL) {
ERR (listview, "could not allocate info memory!\n");
return 0;
}
if ((HOTKEY_INFO*)wndPtr->wExtra[0] != infoPtr) {
ERR (listview, "pointer assignment error!\n");
return 0;
}
/* initialize info structure */
/* get default font height */
hdc = GetDC32 (wndPtr->hwndSelf);
GetTextMetrics32A (hdc, &tm);
infoPtr->nHeight = tm.tmHeight;
ReleaseDC32 (wndPtr->hwndSelf, hdc);
return 0;
}
static LRESULT
HOTKEY_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
/* free hotkey info data */
COMCTL32_Free (infoPtr);
return 0;
}
static LRESULT
HOTKEY_EraseBackground (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
HBRUSH32 hBrush;
RECT32 rc;
hBrush =
(HBRUSH32)SendMessage32A (wndPtr->parent->hwndSelf, WM_CTLCOLOREDIT,
wParam, (LPARAM)wndPtr->hwndSelf);
if (hBrush)
hBrush = (HBRUSH32)GetStockObject32 (WHITE_BRUSH);
GetClientRect32 (wndPtr->hwndSelf, &rc);
FillRect32 ((HDC32)wParam, &rc, hBrush);
return -1;
}
__inline__ static LRESULT
HOTKEY_GetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
return infoPtr->hFont;
}
static LRESULT
HOTKEY_KeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
switch (wParam) {
case VK_RETURN:
case VK_TAB:
case VK_SPACE:
case VK_DELETE:
case VK_ESCAPE:
case VK_BACK:
return DefWindowProc32A (wndPtr->hwndSelf, WM_KEYDOWN, wParam, lParam);
case VK_SHIFT:
case VK_CONTROL:
case VK_MENU:
FIXME (hotkey, "modifier key pressed!\n");
break;
default:
FIXME (hotkey, " %d\n", wParam);
break;
}
return TRUE;
}
static LRESULT
HOTKEY_KeyUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
FIXME (hotkey, " %d\n", wParam);
return 0;
}
static LRESULT
HOTKEY_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
infoPtr->bFocus = FALSE;
DestroyCaret32 ();
return 0;
}
static LRESULT
HOTKEY_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
// HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
SetFocus32 (wndPtr->hwndSelf);
return 0;
}
__inline__ static LRESULT
HOTKEY_NCCreate (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
wndPtr->dwExStyle |= WS_EX_CLIENTEDGE;
return DefWindowProc32A (wndPtr->hwndSelf, WM_NCCREATE, wParam, lParam);
}
static LRESULT
HOTKEY_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
infoPtr->bFocus = TRUE;
CreateCaret32 (wndPtr->hwndSelf, (HBITMAP32)0, 1, infoPtr->nHeight);
SetCaretPos32 (1, 1);
ShowCaret32 (wndPtr->hwndSelf);
return 0;
}
__inline__ static LRESULT
HOTKEY_SetFont (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
TEXTMETRIC32A tm;
HDC32 hdc;
HFONT32 hOldFont = 0;
infoPtr->hFont = (HFONT32)wParam;
hdc = GetDC32 (wndPtr->hwndSelf);
if (infoPtr->hFont)
hOldFont = SelectObject32 (hdc, infoPtr->hFont);
GetTextMetrics32A (hdc, &tm);
infoPtr->nHeight = tm.tmHeight;
if (infoPtr->hFont)
SelectObject32 (hdc, hOldFont);
ReleaseDC32 (wndPtr->hwndSelf, hdc);
if (LOWORD(lParam)) {
FIXME (hotkey, "force redraw!\n");
}
return 0;
}
static LRESULT
HOTKEY_SysKeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
switch (wParam) {
case VK_RETURN:
case VK_TAB:
case VK_SPACE:
case VK_DELETE:
case VK_ESCAPE:
case VK_BACK:
return DefWindowProc32A (wndPtr->hwndSelf, WM_SYSKEYDOWN, wParam, lParam);
case VK_SHIFT:
case VK_CONTROL:
case VK_MENU:
FIXME (hotkey, "modifier key pressed!\n");
break;
default:
FIXME (hotkey, " %d\n", wParam);
break;
}
return TRUE;
}
static LRESULT
HOTKEY_SysKeyUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
{
HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(wndPtr);
FIXME (hotkey, " %d\n", wParam);
return 0;
}
LRESULT WINAPI
HOTKEY_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
{
WND *wndPtr = WIN_FindWndPtr(hwnd);
switch (uMsg)
{
// case HKM_GETHOTKEY:
// case HKM_SETHOTKEY:
// case HKM_SETRULES:
// case WM_CHAR:
case WM_CREATE:
return HOTKEY_Create (wndPtr, wParam, lParam);
case WM_DESTROY:
return HOTKEY_Destroy (wndPtr, wParam, lParam);
case WM_ERASEBKGND:
return HOTKEY_EraseBackground (wndPtr, wParam, lParam);
case WM_GETDLGCODE:
return DLGC_WANTCHARS | DLGC_WANTARROWS;
case WM_GETFONT:
return HOTKEY_GetFont (wndPtr, wParam, lParam);
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
return HOTKEY_KeyDown (wndPtr, wParam, lParam);
case WM_KEYUP:
case WM_SYSKEYUP:
return HOTKEY_KeyUp (wndPtr, wParam, lParam);
case WM_KILLFOCUS:
return HOTKEY_KillFocus (wndPtr, wParam, lParam);
case WM_LBUTTONDOWN:
return HOTKEY_LButtonDown (wndPtr, wParam, lParam);
case WM_NCCREATE:
return HOTKEY_NCCreate (wndPtr, wParam, lParam);
// case WM_PAINT:
case WM_SETFOCUS:
return HOTKEY_SetFocus (wndPtr, wParam, lParam);
case WM_SETFONT:
return HOTKEY_SetFont (wndPtr, wParam, lParam);
// case WM_SYSCHAR:
default:
if (uMsg >= WM_USER)
ERR (hotkey, "unknown msg %04x wp=%08x lp=%08lx\n",
uMsg, wParam, lParam);
return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
}
return 0;
}
VOID
HOTKEY_Register (VOID)
{
WNDCLASS32A wndClass;
if (GlobalFindAtom32A (HOTKEY_CLASS32A)) return;
ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
wndClass.style = CS_GLOBALCLASS;
wndClass.lpfnWndProc = (WNDPROC32)HOTKEY_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(HOTKEY_INFO *);
wndClass.hCursor = 0;
wndClass.hbrBackground = 0;
wndClass.lpszClassName = HOTKEY_CLASS32A;
RegisterClass32A (&wndClass);
}
VOID
HOTKEY_Unregister (VOID)
{
if (GlobalFindAtom32A (HOTKEY_CLASS32A))
UnregisterClass32A (HOTKEY_CLASS32A, (HINSTANCE32)NULL);
}