Sweden-Number/controls/oldlbox.c

768 lines
20 KiB
C
Raw Normal View History

Release 961201 Sat Nov 30 19:21:17 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [configure] Re-generated with autoconf 2.11. Let me know if you have problems. * [controls/listbox.c] [controls/oldlbox.c] Listboxes rewritten from scratch. Moved old code still used by comboboxes to oldlbox.c * [misc/registry.c] Use temporary file when saving registry. * [windows/dialog.c] Implemented Win32 version of DlgDirList() and DlgDirListComboBox(). * [windows/winproc.c] Added translation for listbox Win32 messages. Sat Nov 30 21:00:00 Alex Korobka <alex@trantor.pharm.sunysb.edu> * [controls/widgets.c] [controls/button.c] Fixed some incompatibilities with CTL3D DLL. * [windows/dialog.c] Made dialog windows fit into the desktop. * [misc/winsock.c] [misc/winsock_async.c] New Winsock engine. * [windows/message.c] GetMessage() fixes. * [windows/queue.c] [windows/hook.c] [windows/win.c] SetMessageQueue() fixes. Fri Nov 29 10:25:12 1996 Slaven Rezic <eserte@cs.tu-berlin.de> * [objects/text.c] DrawText16(): Fixed return value. Tue Nov 26 14:47:09 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [files/profile.c] [*/*] Added Win32 profile functions, updated to new naming standard. * [objects/font.c] [if1632/thunk.c] [include/windows.h] Added EnumFonts32*, EnumFontFamiliesEx*, changed prototypes and structures. * [misc/ole2nls.c] [if1632/thunk.c] Added EnumSystemLocales() (winhelp.exe). * [misc/registry.c] Added Windows 3.1 registry loader supplied by Tor Sjxwall, tor@sn.no * [win32/file.c] Partially fixed CreateFileMapping(), added UnmapViewOfFile(). Sat Nov 23 23:36:05 1996 Ronan Waide <waider@waider.ie> * [misc/shell.c] Fixed some FIXMEs relating to ShellExec() and FindExecutable(). * [misc/main.c] Implemented a few more of the SystemParametersInfo() cases. Tue Nov 19 01:24:34 1996 Philippe De Muyter <phdm@info.ucl.ac.be> * [include/keyboard.h] New file, new macro WINE_VKEY_MAPPINGS (using code taken from event.c). * [include/windows.h] New [VK_A, VK_Z] and [VK_0, VK9] macros. * [misc/keyboard.c] Fixes in KeyTable and ToAscii. * [objects/font.c] FONT_init : Give default value for MSWIN "system" font. FONT_MatchFont : Do not try every size of a font family if the family does not exist. * [windows/event.c] lastEventChar hack removed. KeyStateTable replaced by InputKeyStateTable (maintained in event.c) and QueueKeyStateTable (maintained in message.c). EVENT_key : Corrections to the extended bit setting. * [windows/message.c] [windows/keyboard.c] Implementation of a new QueueKeyStateTable : table of key states valid when messages are retrieved by GetMessage or PeekMessage, and valid for TranslateMessage. TranslateMessage : Convert WM*KEY messages using QueueKeyStateTable and ToAscii. Mon Nov 18 16:59:01 1996 Robert Pouliot <krynos@clic.net> * [graphics/Makefile.in] [graphics/wing.c] [if1632/wing.spec] Some functions for WinG support, mostly empty stubs. * [misc/crtdll.c] [if1632/crtdll.spec] Many functions added to CRTDLL, mostly calls to Unix C library.
1996-12-01 18:17:47 +01:00
/*
* Listbox controls
*
* Copyright Martin Ayotte, 1993
* Constantine Sapuntzakis, 1995
* Alex Korobka, 1995, 1996
*
*/
/*
* FIXME:
* - proper scrolling for multicolumn style
* - anchor and caret for LBS_EXTENDEDSEL
* - proper selection with keyboard
* - how to handle (LBS_EXTENDEDSEL | LBS_MULTIPLESEL) style
* - support for LBS_NOINTEGRALHEIGHT and LBS_OWNERDRAWVARIABLE styles
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "windows.h"
#include "win.h"
#include "gdi.h"
#include "listbox.h"
#include "heap.h"
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"
#define LIST_HEAP_ALLOC(lphl,f,size) \
LOCAL_Alloc( lphl->HeapSel, LMEM_FIXED, (size) )
#define LIST_HEAP_FREE(lphl,handle) \
LOCAL_Free( lphl->HeapSel, (handle) )
#define LIST_HEAP_ADDR(lphl,handle) \
((handle) ? PTR_SEG_OFF_TO_LIN(lphl->HeapSel, (handle)) : NULL)
#define LIST_HEAP_SIZE 0x10000
#define LBMM_EDGE 4 /* distance inside box which is same as moving mouse
outside box, to trigger scrolling of LB */
#define MATCH_SUBSTR 2
#define MATCH_EXACT 1
#define MATCH_NEAREST 0
static void ListBoxInitialize(LPHEADLIST lphl)
{
lphl->lpFirst = NULL;
lphl->ItemsCount = 0;
lphl->ItemsVisible = 0;
lphl->FirstVisible = 0;
lphl->ColumnsVisible = 1;
lphl->ItemsPerColumn = 0;
lphl->ItemFocused = -1;
lphl->PrevFocused = -1;
}
void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent)
{
LPHEADLIST lphl;
HDC32 hdc;
lphl = (LPHEADLIST)xmalloc(sizeof(HEADLIST));
SetWindowLong32A(hwnd, 0, (LONG)lphl);
ListBoxInitialize(lphl);
lphl->DrawCtlType = CtlType;
lphl->CtlID = GetWindowWord(hwnd,GWW_ID);
lphl->bRedrawFlag = TRUE;
lphl->iNumStops = 0;
lphl->TabStops = NULL;
lphl->hFont = GetStockObject32(SYSTEM_FONT);
lphl->hSelf = hwnd;
if (CtlType==ODT_COMBOBOX) /* use the "faked" style for COMBOLBOX */
/* LBS_SORT instead CBS_SORT e.g. */
lphl->dwStyle = MAKELONG(LOWORD(styles),HIWORD(GetWindowLong32A(hwnd,GWL_STYLE)));
else
lphl->dwStyle = GetWindowLong32A(hwnd,GWL_STYLE); /* use original style dword */
lphl->hParent = parent;
lphl->StdItemHeight = 15; /* FIXME: should get the font height */
lphl->OwnerDrawn = styles & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE);
lphl->HasStrings = (styles & LBS_HASSTRINGS) || !lphl->OwnerDrawn;
/* create dummy hdc to set text height */
if ((hdc = GetDC32(0)))
{
TEXTMETRIC16 tm;
GetTextMetrics16( hdc, &tm );
lphl->StdItemHeight = tm.tmHeight;
dprintf_listbox(stddeb,"CreateListBoxStruct: font height %d\n",
lphl->StdItemHeight);
ReleaseDC32( 0, hdc );
}
if (lphl->OwnerDrawn)
{
LISTSTRUCT dummyls;
lphl->needMeasure = TRUE;
dummyls.mis.CtlType = lphl->DrawCtlType;
dummyls.mis.CtlID = lphl->CtlID;
dummyls.mis.itemID = -1;
dummyls.mis.itemWidth = 0; /* ignored */
dummyls.mis.itemData = 0;
ListBoxAskMeasure(lphl,&dummyls);
}
lphl->HeapSel = GlobalAlloc16(GMEM_FIXED,LIST_HEAP_SIZE);
LocalInit( lphl->HeapSel, 0, LIST_HEAP_SIZE-1);
}
/* Send notification "code" as part of a WM_COMMAND-message if hwnd
has the LBS_NOTIFY style */
void ListBoxSendNotification(LPHEADLIST lphl, WORD code)
{
if (lphl->dwStyle & LBS_NOTIFY)
SendMessage32A( lphl->hParent, WM_COMMAND,
MAKEWPARAM( lphl->CtlID, code), (LPARAM)lphl->hSelf );
}
/* get the maximum value of lphl->FirstVisible */
int ListMaxFirstVisible(LPHEADLIST lphl)
{
int m = lphl->ItemsCount-lphl->ItemsVisible;
return (m < 0) ? 0 : m;
}
/* Returns: 0 if nothing needs to be changed */
/* 1 if FirstVisible changed */
int ListBoxScrollToFocus(LPHEADLIST lphl)
{
short end;
if (lphl->ItemsCount == 0) return 0;
if (lphl->ItemFocused == -1) return 0;
end = lphl->FirstVisible + lphl->ItemsVisible - 1;
if (lphl->ItemFocused < lphl->FirstVisible ) {
lphl->FirstVisible = lphl->ItemFocused;
return 1;
} else {
if (lphl->ItemFocused > end) {
WORD maxFirstVisible = ListMaxFirstVisible(lphl);
lphl->FirstVisible = lphl->ItemFocused;
if (lphl->FirstVisible > maxFirstVisible) {
lphl->FirstVisible = maxFirstVisible;
}
return 1;
}
}
return 0;
}
LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex)
{
LPLISTSTRUCT lpls;
UINT Count = 0;
if (uIndex >= lphl->ItemsCount) return NULL;
lpls = lphl->lpFirst;
while (Count++ < uIndex) lpls = lpls->lpNext;
return lpls;
}
void ListBoxDrawItem(HWND hwnd, LPHEADLIST lphl, HDC16 hdc, LPLISTSTRUCT lpls,
RECT16 *rect, WORD itemAction, WORD itemState)
{
if (lphl->OwnerDrawn)
{
DRAWITEMSTRUCT32 dis;
dis.CtlID = lpls->mis.CtlID;
dis.CtlType = lpls->mis.CtlType;
dis.itemID = lpls->mis.itemID;
dis.hDC = hdc;
dis.hwndItem = hwnd;
dis.itemData = lpls->mis.itemData;
dis.itemAction = itemAction;
dis.itemState = itemState;
CONV_RECT16TO32( rect, &dis.rcItem );
SendMessage32A( lphl->hParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis );
return;
}
if (itemAction == ODA_DRAWENTIRE || itemAction == ODA_SELECT) {
int OldBkMode;
DWORD dwOldTextColor = 0;
OldBkMode = SetBkMode32(hdc, TRANSPARENT);
Release 961201 Sat Nov 30 19:21:17 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [configure] Re-generated with autoconf 2.11. Let me know if you have problems. * [controls/listbox.c] [controls/oldlbox.c] Listboxes rewritten from scratch. Moved old code still used by comboboxes to oldlbox.c * [misc/registry.c] Use temporary file when saving registry. * [windows/dialog.c] Implemented Win32 version of DlgDirList() and DlgDirListComboBox(). * [windows/winproc.c] Added translation for listbox Win32 messages. Sat Nov 30 21:00:00 Alex Korobka <alex@trantor.pharm.sunysb.edu> * [controls/widgets.c] [controls/button.c] Fixed some incompatibilities with CTL3D DLL. * [windows/dialog.c] Made dialog windows fit into the desktop. * [misc/winsock.c] [misc/winsock_async.c] New Winsock engine. * [windows/message.c] GetMessage() fixes. * [windows/queue.c] [windows/hook.c] [windows/win.c] SetMessageQueue() fixes. Fri Nov 29 10:25:12 1996 Slaven Rezic <eserte@cs.tu-berlin.de> * [objects/text.c] DrawText16(): Fixed return value. Tue Nov 26 14:47:09 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [files/profile.c] [*/*] Added Win32 profile functions, updated to new naming standard. * [objects/font.c] [if1632/thunk.c] [include/windows.h] Added EnumFonts32*, EnumFontFamiliesEx*, changed prototypes and structures. * [misc/ole2nls.c] [if1632/thunk.c] Added EnumSystemLocales() (winhelp.exe). * [misc/registry.c] Added Windows 3.1 registry loader supplied by Tor Sjxwall, tor@sn.no * [win32/file.c] Partially fixed CreateFileMapping(), added UnmapViewOfFile(). Sat Nov 23 23:36:05 1996 Ronan Waide <waider@waider.ie> * [misc/shell.c] Fixed some FIXMEs relating to ShellExec() and FindExecutable(). * [misc/main.c] Implemented a few more of the SystemParametersInfo() cases. Tue Nov 19 01:24:34 1996 Philippe De Muyter <phdm@info.ucl.ac.be> * [include/keyboard.h] New file, new macro WINE_VKEY_MAPPINGS (using code taken from event.c). * [include/windows.h] New [VK_A, VK_Z] and [VK_0, VK9] macros. * [misc/keyboard.c] Fixes in KeyTable and ToAscii. * [objects/font.c] FONT_init : Give default value for MSWIN "system" font. FONT_MatchFont : Do not try every size of a font family if the family does not exist. * [windows/event.c] lastEventChar hack removed. KeyStateTable replaced by InputKeyStateTable (maintained in event.c) and QueueKeyStateTable (maintained in message.c). EVENT_key : Corrections to the extended bit setting. * [windows/message.c] [windows/keyboard.c] Implementation of a new QueueKeyStateTable : table of key states valid when messages are retrieved by GetMessage or PeekMessage, and valid for TranslateMessage. TranslateMessage : Convert WM*KEY messages using QueueKeyStateTable and ToAscii. Mon Nov 18 16:59:01 1996 Robert Pouliot <krynos@clic.net> * [graphics/Makefile.in] [graphics/wing.c] [if1632/wing.spec] Some functions for WinG support, mostly empty stubs. * [misc/crtdll.c] [if1632/crtdll.spec] Many functions added to CRTDLL, mostly calls to Unix C library.
1996-12-01 18:17:47 +01:00
if (itemState != 0) {
dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
FillRect16(hdc, rect, GetStockObject32(BLACK_BRUSH));
}
if (lphl->dwStyle & LBS_USETABSTOPS) {
TabbedTextOut(hdc, rect->left + 5, rect->top + 2,
(char *)lpls->itemText, strlen((char *)lpls->itemText),
lphl->iNumStops, lphl->TabStops, 0);
} else {
TextOut16(hdc, rect->left + 5, rect->top + 2,
(char *)lpls->itemText, strlen((char *)lpls->itemText));
}
if (itemState != 0) {
SetTextColor(hdc, dwOldTextColor);
}
SetBkMode32(hdc, OldBkMode);
Release 961201 Sat Nov 30 19:21:17 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [configure] Re-generated with autoconf 2.11. Let me know if you have problems. * [controls/listbox.c] [controls/oldlbox.c] Listboxes rewritten from scratch. Moved old code still used by comboboxes to oldlbox.c * [misc/registry.c] Use temporary file when saving registry. * [windows/dialog.c] Implemented Win32 version of DlgDirList() and DlgDirListComboBox(). * [windows/winproc.c] Added translation for listbox Win32 messages. Sat Nov 30 21:00:00 Alex Korobka <alex@trantor.pharm.sunysb.edu> * [controls/widgets.c] [controls/button.c] Fixed some incompatibilities with CTL3D DLL. * [windows/dialog.c] Made dialog windows fit into the desktop. * [misc/winsock.c] [misc/winsock_async.c] New Winsock engine. * [windows/message.c] GetMessage() fixes. * [windows/queue.c] [windows/hook.c] [windows/win.c] SetMessageQueue() fixes. Fri Nov 29 10:25:12 1996 Slaven Rezic <eserte@cs.tu-berlin.de> * [objects/text.c] DrawText16(): Fixed return value. Tue Nov 26 14:47:09 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [files/profile.c] [*/*] Added Win32 profile functions, updated to new naming standard. * [objects/font.c] [if1632/thunk.c] [include/windows.h] Added EnumFonts32*, EnumFontFamiliesEx*, changed prototypes and structures. * [misc/ole2nls.c] [if1632/thunk.c] Added EnumSystemLocales() (winhelp.exe). * [misc/registry.c] Added Windows 3.1 registry loader supplied by Tor Sjxwall, tor@sn.no * [win32/file.c] Partially fixed CreateFileMapping(), added UnmapViewOfFile(). Sat Nov 23 23:36:05 1996 Ronan Waide <waider@waider.ie> * [misc/shell.c] Fixed some FIXMEs relating to ShellExec() and FindExecutable(). * [misc/main.c] Implemented a few more of the SystemParametersInfo() cases. Tue Nov 19 01:24:34 1996 Philippe De Muyter <phdm@info.ucl.ac.be> * [include/keyboard.h] New file, new macro WINE_VKEY_MAPPINGS (using code taken from event.c). * [include/windows.h] New [VK_A, VK_Z] and [VK_0, VK9] macros. * [misc/keyboard.c] Fixes in KeyTable and ToAscii. * [objects/font.c] FONT_init : Give default value for MSWIN "system" font. FONT_MatchFont : Do not try every size of a font family if the family does not exist. * [windows/event.c] lastEventChar hack removed. KeyStateTable replaced by InputKeyStateTable (maintained in event.c) and QueueKeyStateTable (maintained in message.c). EVENT_key : Corrections to the extended bit setting. * [windows/message.c] [windows/keyboard.c] Implementation of a new QueueKeyStateTable : table of key states valid when messages are retrieved by GetMessage or PeekMessage, and valid for TranslateMessage. TranslateMessage : Convert WM*KEY messages using QueueKeyStateTable and ToAscii. Mon Nov 18 16:59:01 1996 Robert Pouliot <krynos@clic.net> * [graphics/Makefile.in] [graphics/wing.c] [if1632/wing.spec] Some functions for WinG support, mostly empty stubs. * [misc/crtdll.c] [if1632/crtdll.spec] Many functions added to CRTDLL, mostly calls to Unix C library.
1996-12-01 18:17:47 +01:00
}
else DrawFocusRect16(hdc, rect);
}
int ListBoxFindMouse(LPHEADLIST lphl, int X, int Y)
{
LPLISTSTRUCT lpls = lphl->lpFirst;
int i, j;
POINT16 point;
point.x = X; point.y = Y;
if (lphl->ItemsCount == 0) return LB_ERR;
for(i = 0; i < lphl->FirstVisible; i++) {
if (lpls == NULL) return LB_ERR;
lpls = lpls->lpNext;
}
for(j = 0; j < lphl->ItemsVisible; i++, j++) {
if (lpls == NULL) return LB_ERR;
if (PtInRect16(&lpls->itemRect,point)) {
return i;
}
lpls = lpls->lpNext;
}
dprintf_listbox(stddeb,"ListBoxFindMouse: not found\n");
return LB_ERR;
}
BOOL32 lbDeleteItemNotify(LPHEADLIST lphl, LPLISTSTRUCT lpls)
{
/* called only for owner drawn listboxes */
BOOL32 ret;
DELETEITEMSTRUCT16 *delItem = SEGPTR_NEW(DELETEITEMSTRUCT16);
if (!delItem) return FALSE;
delItem->CtlType = lphl->DrawCtlType;
delItem->CtlID = lphl->CtlID;
delItem->itemID = lpls->mis.itemID;
delItem->hwndItem = lphl->hSelf;
delItem->itemData = lpls->mis.itemData;
ret = SendMessage16( lphl->hParent, WM_DELETEITEM, (WPARAM16)lphl->CtlID,
(LPARAM)SEGPTR_GET(delItem) );
SEGPTR_FREE(delItem);
return ret;
}
/* -------------------- strings and item data ---------------------- */
void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls)
{
MEASUREITEMSTRUCT16 *lpmeasure = SEGPTR_NEW(MEASUREITEMSTRUCT16);
if (!lpmeasure) return;
*lpmeasure = lpls->mis;
lpmeasure->itemHeight = lphl->StdItemHeight;
SendMessage16( lphl->hParent, WM_MEASUREITEM, lphl->CtlID,
(LPARAM)SEGPTR_GET(lpmeasure) );
if (lphl->dwStyle & LBS_OWNERDRAWFIXED)
{
if (lpmeasure->itemHeight > lphl->StdItemHeight)
lphl->StdItemHeight = lpmeasure->itemHeight;
lpls->mis.itemHeight = lpmeasure->itemHeight;
}
SEGPTR_FREE(lpmeasure);
}
static LPLISTSTRUCT ListBoxCreateItem(LPHEADLIST lphl, int id)
{
LPLISTSTRUCT lplsnew = (LPLISTSTRUCT)malloc(sizeof(LISTSTRUCT));
if (lplsnew == NULL) return NULL;
lplsnew->itemState = 0;
lplsnew->mis.CtlType = lphl->DrawCtlType;
lplsnew->mis.CtlID = lphl->CtlID;
lplsnew->mis.itemID = id;
lplsnew->mis.itemHeight = lphl->StdItemHeight;
lplsnew->mis.itemWidth = 0; /* ignored */
lplsnew->mis.itemData = 0;
SetRectEmpty16( &lplsnew->itemRect );
return lplsnew;
}
static int ListBoxAskCompare(LPHEADLIST lphl, int startItem, SEGPTR matchData, BOOL exactMatch )
{
/* Do binary search for sorted listboxes. Linked list item storage sort of
* defeats the purpose ( forces to traverse item list all the time ) but M$ does it this way...
*
* MATCH_NEAREST (0) - return position for insertion - for all styles
* MATCH_EXACT (1) - search for an item, return index or LB_ERR
* MATCH_SUBSTR (2) - same as exact match but with strncmp for string comparision
*/
COMPAREITEMSTRUCT16 *itemCmp;
LPLISTSTRUCT currentItem = NULL;
LPCSTR matchStr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(matchData):NULL;
int head, pos = -1, tail, loop = 1;
short b = 0, s_length = 0;
/* check if empty */
if( !lphl->ItemsCount )
return (exactMatch)? LB_ERR: 0;
/* set up variables */
if( exactMatch == MATCH_NEAREST )
startItem = 0;
else if( ++startItem )
{
loop = 2;
if( startItem >= lphl->ItemsCount ) startItem = lphl->ItemsCount - 1;
}
if( exactMatch == MATCH_SUBSTR && lphl->HasStrings )
{
s_length = strlen( matchStr );
if( !s_length ) return 0; /* head of the list - empty string */
}
head = startItem; tail = lphl->ItemsCount - 1;
dprintf_listbox(stddeb,"AskCompare: head = %i, tail = %i, data = %08x\n", head, tail, (unsigned)matchData );
if (!(itemCmp = SEGPTR_NEW(COMPAREITEMSTRUCT16))) return 0;
itemCmp->CtlType = lphl->DrawCtlType;
itemCmp->CtlID = lphl->CtlID;
itemCmp->hwndItem = lphl->hSelf;
/* search from startItem */
while ( loop-- )
{
while( head <= tail )
{
pos = (tail + head)/2;
currentItem = ListBoxGetItem( lphl, pos );
if( lphl->HasStrings )
{
b = ( s_length )? lstrncmpi32A( currentItem->itemText, matchStr, s_length)
: lstrcmpi32A( currentItem->itemText, matchStr);
}
else
{
itemCmp->itemID1 = pos;
itemCmp->itemData1 = currentItem->mis.itemData;
itemCmp->itemID2 = -1;
itemCmp->itemData2 = matchData;
b = SendMessage16( lphl->hParent, WM_COMPAREITEM,
(WPARAM16)lphl->CtlID,
(LPARAM)SEGPTR_GET(itemCmp) );
}
if( b == 0 )
{
SEGPTR_FREE(itemCmp);
return pos; /* found exact match */
}
else
if( b < 0 ) head = ++pos;
else
if( b > 0 ) tail = pos - 1;
}
/* reset to search from the first item */
head = 0; tail = startItem - 1;
}
dprintf_listbox(stddeb,"\t-> pos = %i\n", pos );
SEGPTR_FREE(itemCmp);
/* if we got here match is not exact */
if( pos < 0 ) pos = 0;
else if( pos > lphl->ItemsCount ) pos = lphl->ItemsCount;
return (exactMatch)? LB_ERR: pos;
}
int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr)
{
LPLISTSTRUCT *lppls, lplsnew, lpls;
HANDLE16 hStr;
LPSTR str;
UINT Count;
dprintf_listbox(stddeb,"ListBoxInsertString(%d, %p);\n", uIndex, newstr);
if (!newstr) return -1;
if (uIndex == (UINT)-1)
uIndex = lphl->ItemsCount;
lppls = &lphl->lpFirst;
for(Count = 0; Count < uIndex; Count++) {
if (*lppls == NULL) return LB_ERR;
lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext;
}
lplsnew = ListBoxCreateItem(lphl, Count);
if (lplsnew == NULL) {
fprintf(stdnimp,"ListBoxInsertString() out of memory !\n");
return LB_ERRSPACE;
}
lplsnew->lpNext = *lppls;
*lppls = lplsnew;
lphl->ItemsCount++;
hStr = 0;
if (lphl->HasStrings) {
dprintf_listbox(stddeb," string: %s\n", newstr);
hStr = LIST_HEAP_ALLOC(lphl, LMEM_MOVEABLE, strlen(newstr) + 1);
str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr);
if (str == NULL) return LB_ERRSPACE;
strcpy(str, newstr);
lplsnew->itemText = str;
/* I'm not so sure about the next one */
lplsnew->mis.itemData = 0;
} else {
lplsnew->itemText = NULL;
lplsnew->mis.itemData = (DWORD)newstr;
}
lplsnew->mis.itemID = uIndex;
lplsnew->hData = hStr;
/* adjust the itemID field of the following entries */
for(lpls = lplsnew->lpNext; lpls != NULL; lpls = lpls->lpNext) {
lpls->mis.itemID++;
}
if (lphl->needMeasure) {
ListBoxAskMeasure(lphl, lplsnew);
}
dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount);
return uIndex;
}
int ListBoxAddString(LPHEADLIST lphl, SEGPTR itemData)
{
UINT pos = (UINT) -1;
LPCSTR newstr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(itemData):(LPCSTR)itemData;
if ( lphl->dwStyle & LBS_SORT )
pos = ListBoxAskCompare( lphl, -1, itemData, MATCH_NEAREST );
return ListBoxInsertString(lphl, pos, newstr);
}
int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr)
{
LPLISTSTRUCT lpls;
if (!OutStr) {
dprintf_listbox(stddeb, "ListBoxGetText // OutStr==NULL\n");
return 0;
}
*OutStr = '\0';
lpls = ListBoxGetItem (lphl, uIndex);
if (lpls == NULL) return LB_ERR;
if (!lphl->HasStrings) {
*((long *)OutStr) = lpls->mis.itemData;
return 4;
}
strcpy(OutStr, lpls->itemText);
return strlen(OutStr);
}
DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex)
{
LPLISTSTRUCT lpls;
lpls = ListBoxGetItem (lphl, uIndex);
if (lpls == NULL) return LB_ERR;
return lpls->mis.itemData;
}
int ListBoxSetItemData(LPHEADLIST lphl, UINT uIndex, DWORD ItemData)
{
LPLISTSTRUCT lpls = ListBoxGetItem(lphl, uIndex);
if (lpls == NULL) return LB_ERR;
lpls->mis.itemData = ItemData;
return 1;
}
int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex)
{
LPLISTSTRUCT lpls, lpls2;
UINT Count;
if (uIndex >= lphl->ItemsCount) return LB_ERR;
lpls = lphl->lpFirst;
if (lpls == NULL) return LB_ERR;
if (uIndex == 0)
{
if( lphl->OwnerDrawn )
lbDeleteItemNotify( lphl, lpls);
lphl->lpFirst = lpls->lpNext;
}
else
{
LPLISTSTRUCT lpls2 = NULL;
for(Count = 0; Count < uIndex; Count++) {
if (lpls->lpNext == NULL) return LB_ERR;
lpls2 = lpls;
lpls = (LPLISTSTRUCT)lpls->lpNext;
}
if( lphl->OwnerDrawn )
lbDeleteItemNotify( lphl, lpls);
lpls2->lpNext = lpls->lpNext;
}
/* adjust the itemID field of the following entries */
for(lpls2 = lpls->lpNext; lpls2 != NULL; lpls2 = lpls2->lpNext) {
lpls2->mis.itemID--;
}
lphl->ItemsCount--;
if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
free(lpls);
return lphl->ItemsCount;
}
static int lbFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr, BOOL match)
{
/* match is either MATCH_SUBSTR or MATCH_EXACT */
LPLISTSTRUCT lpls;
UINT Count;
UINT First = nFirst + 1;
int s_length = 0;
LPSTR lpMatchStr = (LPSTR)MatchStr;
if (First > lphl->ItemsCount) return LB_ERR;
if (lphl->dwStyle & LBS_SORT )
return ListBoxAskCompare( lphl, nFirst, MatchStr, match );
if (lphl->HasStrings )
{
lpMatchStr = PTR_SEG_TO_LIN(MatchStr);
if( match == MATCH_SUBSTR )
{
s_length = strlen(lpMatchStr);
if( !s_length ) return (lphl->ItemsCount)?0:LB_ERR;
}
}
lpls = ListBoxGetItem(lphl, First);
Count = 0;
while(lpls != NULL)
{
if (lphl->HasStrings)
{
if ( ( s_length )? !lstrncmpi32A(lpls->itemText, lpMatchStr, s_length)
: !lstrcmpi32A(lpls->itemText, lpMatchStr) ) return Count;
}
else
if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
lpls = lpls->lpNext;
Count++;
}
/* Start over at top */
Count = 0;
lpls = lphl->lpFirst;
while (Count < First)
{
if (lphl->HasStrings)
{
if ( ( s_length )? !lstrncmpi32A(lpls->itemText, lpMatchStr, s_length)
: !lstrcmpi32A(lpls->itemText, lpMatchStr) ) return Count;
}
else
if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
lpls = lpls->lpNext;
Count++;
}
return LB_ERR;
}
int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
{
return lbFindString(lphl, nFirst, MatchStr, MATCH_SUBSTR );
}
int ListBoxFindStringExact(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
{
return lbFindString(lphl, nFirst, MatchStr, MATCH_EXACT );
}
int ListBoxResetContent(LPHEADLIST lphl)
{
LPLISTSTRUCT lpls;
int i;
if (lphl->ItemsCount == 0) return 0;
dprintf_listbox(stddeb, "ListBoxResetContent // ItemCount = %d\n",
lphl->ItemsCount);
for(i = 0; i < lphl->ItemsCount; i++) {
lpls = lphl->lpFirst;
if (lpls == NULL) return LB_ERR;
if (lphl->OwnerDrawn) lbDeleteItemNotify(lphl, lpls);
lphl->lpFirst = lpls->lpNext;
if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
free(lpls);
}
ListBoxInitialize(lphl);
return TRUE;
}
/* --------------------- selection ------------------------- */
int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex)
{
LPLISTSTRUCT lpls;
/* use ListBoxSetSel instead */
if (lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) return 0;
/* unselect previous item */
if (lphl->ItemFocused != -1) {
lphl->PrevFocused = lphl->ItemFocused;
lpls = ListBoxGetItem(lphl, lphl->ItemFocused);
if (lpls == 0) return LB_ERR;
lpls->itemState = 0;
}
if ((wIndex != (UINT)-1) && (wIndex < lphl->ItemsCount))
{
lphl->ItemFocused = wIndex;
lpls = ListBoxGetItem(lphl, wIndex);
if (lpls == 0) return LB_ERR;
lpls->itemState = ODS_SELECTED | ODS_FOCUS;
return 0;
}
return LB_ERR;
}
/* ------------------------- dir listing ------------------------ */
LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec)
{
Release 970101 Wed Jan 1 15:36:17 1997 Alexandre Julliard <julliard@lrc.epfl.ch> * [controls/listbox.c] Use FindFirstFile/FindNextFile in LISTBOX_Directory. * [files/dos_fs.c] Rewrote FindFirstFile/FindNextFile to use DOSFS_FindNext(). * [files/file.c] [files/directory.c] Use Win32 kernel objects and handles for file handles. Unified SearchPath() and OpenFile(). * [loader/builtin.c] Moved to if1632/ directory. * [tools/build.c] [debugger/*] [miscemu/*] Win16 register functions now receive the same CONTEXT * structure as Win32 functions. * [include/sigcontext.h] [miscemu/instr.c] Added new macros to get register values from the SIGCONTEXT structure (only used for instruction emulation now). * [scheduler/process.c] [scheduler/thread.c] (New files) Allocate process and thread structures. * [scheduler/process.c] [win32/k32obj.c] Added Win32 kernel objects and handles management. * [loader/task.c] Create a Win32 process and thread for every Win16 task. * [misc/commdlg.c] [misc/shell.c] [windows/msgbox.c] Built-in resources are now in Win32 format. This also avoids 16-bit callbacks for built-in dialogs. * [misc/lzexpand.c] Differentiate between 16-bit and 32-bit file handles. * [miscemu/int*.c] Moved all int emulation to msdos/ directory. * [msdos/*] New directory msdos/ contains all MS-DOS emulation code that can also be used for Winelib; this should enable Winelib apps to use DOS3Call and related functions. * [rc/winerc.c] A few bug fixes for Win32 resource format. * [windows/winpos.c] Hack in WINPOS_ReorderOwnerPopups() to avoid X crashed (still not right though). Sun Dec 29 17:47:55 1996 O. Flebbe <flebbe@science-computing.uni-tuebingen.de> * [loader/pe_image.c] Make sure BSS of a PE_Image is zero. Sat Dec 28 22:15:34 1996 Alex Korobka <alex@trantor.pharm.sunysb.edu> * [windows/scroll.c] ScrollWindowEx() rewrite, ScrollDC() fix. * [windows/nonclient.c] [controls/menu.c] Fixed Alt-Space crashes in dialogs. * [windows/event.c] [windows/message.c] Some changes in mouse message generation. Thu Dec 26 09:25:24 1996 Philippe De Muyter <phdm@info.ucl.ac.be> * [debugger/stabs.c] Dummy DEBUG_ReadExecutableDbgInfo provided for !__ELF__ case. Tue Dec 24 00:59:05 MET 1996 Martin Buck <martin-2.buck@student.uni-ulm.de> * [windows/event.c] Changed XK_Page_{Up,Down} to XK_{Prior,Next} for X11R5 compatibility.
1997-01-01 18:29:55 +01:00
return 0;
Release 961201 Sat Nov 30 19:21:17 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [configure] Re-generated with autoconf 2.11. Let me know if you have problems. * [controls/listbox.c] [controls/oldlbox.c] Listboxes rewritten from scratch. Moved old code still used by comboboxes to oldlbox.c * [misc/registry.c] Use temporary file when saving registry. * [windows/dialog.c] Implemented Win32 version of DlgDirList() and DlgDirListComboBox(). * [windows/winproc.c] Added translation for listbox Win32 messages. Sat Nov 30 21:00:00 Alex Korobka <alex@trantor.pharm.sunysb.edu> * [controls/widgets.c] [controls/button.c] Fixed some incompatibilities with CTL3D DLL. * [windows/dialog.c] Made dialog windows fit into the desktop. * [misc/winsock.c] [misc/winsock_async.c] New Winsock engine. * [windows/message.c] GetMessage() fixes. * [windows/queue.c] [windows/hook.c] [windows/win.c] SetMessageQueue() fixes. Fri Nov 29 10:25:12 1996 Slaven Rezic <eserte@cs.tu-berlin.de> * [objects/text.c] DrawText16(): Fixed return value. Tue Nov 26 14:47:09 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [files/profile.c] [*/*] Added Win32 profile functions, updated to new naming standard. * [objects/font.c] [if1632/thunk.c] [include/windows.h] Added EnumFonts32*, EnumFontFamiliesEx*, changed prototypes and structures. * [misc/ole2nls.c] [if1632/thunk.c] Added EnumSystemLocales() (winhelp.exe). * [misc/registry.c] Added Windows 3.1 registry loader supplied by Tor Sjxwall, tor@sn.no * [win32/file.c] Partially fixed CreateFileMapping(), added UnmapViewOfFile(). Sat Nov 23 23:36:05 1996 Ronan Waide <waider@waider.ie> * [misc/shell.c] Fixed some FIXMEs relating to ShellExec() and FindExecutable(). * [misc/main.c] Implemented a few more of the SystemParametersInfo() cases. Tue Nov 19 01:24:34 1996 Philippe De Muyter <phdm@info.ucl.ac.be> * [include/keyboard.h] New file, new macro WINE_VKEY_MAPPINGS (using code taken from event.c). * [include/windows.h] New [VK_A, VK_Z] and [VK_0, VK9] macros. * [misc/keyboard.c] Fixes in KeyTable and ToAscii. * [objects/font.c] FONT_init : Give default value for MSWIN "system" font. FONT_MatchFont : Do not try every size of a font family if the family does not exist. * [windows/event.c] lastEventChar hack removed. KeyStateTable replaced by InputKeyStateTable (maintained in event.c) and QueueKeyStateTable (maintained in message.c). EVENT_key : Corrections to the extended bit setting. * [windows/message.c] [windows/keyboard.c] Implementation of a new QueueKeyStateTable : table of key states valid when messages are retrieved by GetMessage or PeekMessage, and valid for TranslateMessage. TranslateMessage : Convert WM*KEY messages using QueueKeyStateTable and ToAscii. Mon Nov 18 16:59:01 1996 Robert Pouliot <krynos@clic.net> * [graphics/Makefile.in] [graphics/wing.c] [if1632/wing.spec] Some functions for WinG support, mostly empty stubs. * [misc/crtdll.c] [if1632/crtdll.spec] Many functions added to CRTDLL, mostly calls to Unix C library.
1996-12-01 18:17:47 +01:00
}
/* ------------------------- dimensions ------------------------- */
int ListBoxGetItemRect(LPHEADLIST lphl, WORD wIndex, LPRECT16 lprect)
{
LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wIndex);
dprintf_listbox(stddeb,"ListBox LB_GETITEMRECT %i %p", wIndex,lpls);
if (lpls == NULL)
{
if (lphl->dwStyle & LBS_OWNERDRAWVARIABLE)
return LB_ERR;
else
{
GetClientRect16(lphl->hSelf,lprect);
lprect->bottom=lphl->StdItemHeight;
if (lprect->right<0) lprect->right=0;
}
}
else
*lprect = lpls->itemRect;
dprintf_listbox(stddeb," = %d,%d %d,%d\n", lprect->left,lprect->top,
lprect->right,lprect->bottom);
return 0;
}
int ListBoxSetItemHeight(LPHEADLIST lphl, WORD wIndex, long height)
{
LPLISTSTRUCT lpls;
if (!(lphl->dwStyle & LBS_OWNERDRAWVARIABLE)) {
lphl->StdItemHeight = (short)height;
return 0;
}
lpls = ListBoxGetItem(lphl, wIndex);
if (lpls == NULL) return LB_ERR;
lpls->mis.itemHeight = height;
return 0;
}
/* -------------------------- string search ------------------------ */
int ListBoxFindNextMatch(LPHEADLIST lphl, WORD wChar)
{
LPLISTSTRUCT lpls;
UINT count,first;
if ((char)wChar < ' ') return LB_ERR;
if (!lphl->HasStrings) return LB_ERR;
lpls = lphl->lpFirst;
for (count = 0; lpls != NULL; lpls = lpls->lpNext, count++) {
if (tolower(*lpls->itemText) == tolower((char)wChar)) break;
}
if (lpls == NULL) return LB_ERR;
first = count;
for(; lpls != NULL; lpls = lpls->lpNext, count++) {
if (*lpls->itemText != (char)wChar)
break;
if ((short) count > lphl->ItemFocused)
return count;
}
return first;
}