summaryrefslogtreecommitdiff
path: root/app/wlib/mswlib/mswlist.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2016-12-28 16:52:56 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2016-12-28 16:52:56 +0100
commit7b358424ebad9349421acd533c2fa1cbf6cf3e3e (patch)
tree686678532eefed525c242fd214d0cfb2914726c5 /app/wlib/mswlib/mswlist.c
Initial import of xtrkcad version 1:4.0.2-2
Diffstat (limited to 'app/wlib/mswlib/mswlist.c')
-rw-r--r--app/wlib/mswlib/mswlist.c1173
1 files changed, 1173 insertions, 0 deletions
diff --git a/app/wlib/mswlib/mswlist.c b/app/wlib/mswlib/mswlist.c
new file mode 100644
index 0000000..968624a
--- /dev/null
+++ b/app/wlib/mswlib/mswlist.c
@@ -0,0 +1,1173 @@
+#include <windows.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <commdlg.h>
+#include <math.h>
+#include "mswint.h"
+
+/*
+ *****************************************************************************
+ *
+ * List Boxes
+ *
+ *****************************************************************************
+ */
+
+static XWNDPROC oldListProc = NULL;
+static XWNDPROC newListProc;
+static XWNDPROC oldComboProc = NULL;
+static XWNDPROC newComboProc;
+
+struct wList_t {
+ WOBJ_COMMON
+ int count;
+ int last;
+ long * valueP;
+ wListCallBack_p action;
+ wBool_t editable;
+ int colCnt;
+ wPos_t * colWidths;
+ wBool_t * colRightJust;
+ const char * * colTitles;
+ wPos_t maxWidth;
+ wPos_t scrollPos;
+ HWND hScrollWnd;
+ wPos_t scrollH;
+ wPos_t dragPos;
+ int dragCol;
+ wPos_t dragColWidth;
+ };
+
+
+typedef struct {
+ void * itemContext;
+ wIcon_p bm;
+ wBool_t selected;
+ } listData;
+
+static int LIST_HEIGHT = 19;
+static int listTitleHeight = 16;
+
+
+void wListClear(
+ wList_p b )
+{
+ UINT msg;
+ if (b->type==B_LIST)
+ msg = LB_RESETCONTENT;
+ else
+ msg = CB_RESETCONTENT;
+ SendMessage( b->hWnd, msg, 0, 0 );
+ b->last = -1;
+ b->count = 0;
+}
+
+
+
+void wListSetSize( wList_p bl, wPos_t w, wPos_t h )
+{
+ int rc;
+ RECT rect;
+ wPos_t y;
+
+ bl->w = w;
+ bl->h = h;
+ y = bl->y;
+ if ( bl->hScrollWnd && bl->maxWidth > bl->w )
+ h -= bl->scrollH;
+ if ( bl->colTitles ) {
+ h -= listTitleHeight;
+ y += listTitleHeight;
+ }
+ rc = SetWindowPos( bl->hWnd, HWND_TOP, 0, 0,
+ w, h, SWP_NOMOVE|SWP_NOZORDER);
+ if ( bl->hScrollWnd ) {
+ if ( bl->maxWidth > bl->w ) {
+ GetClientRect( bl->hWnd, &rect );
+ rc = SetWindowPos( bl->hScrollWnd, HWND_TOP, bl->x, y+rect.bottom+2,
+ bl->w, bl->scrollH, SWP_NOZORDER);
+ ShowWindow( bl->hScrollWnd, SW_SHOW );
+ } else {
+ ShowWindow( bl->hScrollWnd, SW_HIDE );
+ }
+ }
+
+}
+
+
+void wListSetIndex(
+ wList_p bl,
+ int index )
+{
+ listData * ldp;
+
+ wListGetCount(bl);
+ if ( index >= bl->count )
+ index = bl->count-1;
+ if ( bl->last == index && index == -1 )
+ return;
+ if ( bl->type==B_LIST && (bl->option&BL_MANY) != 0 ) {
+ if ( bl->last != -1 )
+ SendMessage( bl->hWnd, LB_SETSEL, 0, MAKELPARAM(bl->last,0) );
+ if ( index >= 0 )
+ SendMessage( bl->hWnd, LB_SETSEL, 1, MAKELPARAM(index, 0) );
+ } else {
+ SendMessage( bl->hWnd,
+ bl->type==B_LIST?LB_SETCURSEL:CB_SETCURSEL, index, 0 );
+ }
+ if ( bl->last >= 0 ) {
+ ldp = (listData*)SendMessage( bl->hWnd,
+ (bl->type==B_LIST?LB_GETITEMDATA:CB_GETITEMDATA),
+ bl->last, 0L );
+ if ( ldp && ldp!=(void*)LB_ERR )
+ ldp->selected = FALSE;
+ }
+ if ( index >= 0 ) {
+ ldp = (listData*)SendMessage( bl->hWnd,
+ (bl->type==B_LIST?LB_GETITEMDATA:CB_GETITEMDATA),
+ index, 0L );
+ if ( ldp && ldp!=(void*)LB_ERR )
+ ldp->selected = TRUE;
+ }
+ /*if (b->option&BL_ICON)*/
+ InvalidateRect( bl->hWnd, NULL, FALSE );
+ bl->last = index;
+}
+
+
+wIndex_t wListGetIndex(
+ wList_p b )
+{
+ return b->last;
+}
+
+
+void wListSetActive(
+ wList_p b,
+ int inx,
+ wBool_t active )
+{
+}
+
+
+void wListSetEditable(
+ wList_p b,
+ wBool_t editable )
+{
+ b->editable = editable;
+}
+
+
+void wListSetValue(
+ wList_p bl,
+ const char * val )
+{
+ if ( bl->type == B_DROPLIST ) {
+ SendMessage( bl->hWnd, WM_SETTEXT, 0, (DWORD)(LPSTR)val );
+ bl->last = -1;
+ }
+}
+
+
+wIndex_t wListFindValue(
+ wList_p bl,
+ const char * val )
+{
+ wIndex_t inx;
+ WORD cnt;
+ wListGetCount(bl);
+ for ( inx = 0; inx < bl->count ; inx++ ) {
+ cnt = (int)SendMessage( bl->hWnd,
+ (bl->type==B_LIST?LB_GETTEXT:CB_GETLBTEXT), inx,
+ (DWORD)(LPSTR)mswTmpBuff );
+ mswTmpBuff[cnt] = '\0';
+ if ( strcmp( val, mswTmpBuff ) == 0 )
+ return inx;
+ }
+ return -1;
+}
+
+
+wIndex_t wListGetValues(
+ wList_p bl,
+ char * s,
+ int siz,
+ void * * listContextRef,
+ void * * itemContextRef )
+{
+ WORD cnt;
+ WORD msg;
+ WORD inx = bl->last;
+ listData *ldp = NULL;
+ if ( bl->type==B_DROPLIST && bl->last < 0 ) {
+ msg = WM_GETTEXT;
+ inx = sizeof mswTmpBuff;
+ } else {
+ if ( bl->last < 0 )
+ goto EMPTY;
+ if ( bl->type==B_LIST ) {
+ msg = LB_GETTEXT;
+ } else {
+ msg = CB_GETLBTEXT;
+ }
+ }
+ cnt = (int)SendMessage( bl->hWnd, msg, inx, (DWORD)(LPSTR)mswTmpBuff );
+ mswTmpBuff[cnt] = '\0';
+ if (s)
+ strncpy( s, mswTmpBuff, siz );
+ if (bl->last >= 0) {
+ ldp = (listData*)SendMessage( bl->hWnd,
+ (bl->type==B_LIST?LB_GETITEMDATA:CB_GETITEMDATA),
+ bl->last, 0L );
+ if ( ldp==(listData*)LB_ERR )
+ ldp = NULL;
+ } else {
+ ldp = NULL;
+ }
+EMPTY:
+ if (itemContextRef)
+ *itemContextRef = (ldp?ldp->itemContext:NULL);
+ if (listContextRef)
+ *listContextRef = bl->data;
+ return bl->last;
+}
+
+wBool_t wListSetValues(
+ wList_p b,
+ wIndex_t inx,
+ const char * labelStr,
+ wIcon_p bm,
+ void * itemData )
+{
+ listData * ldp;
+ WORD curSel;
+ ldp = (listData*)malloc( sizeof *ldp );
+ ldp->itemContext = itemData;
+ ldp->bm = bm;
+ ldp->selected = FALSE;
+ if ( (b->option&BL_MANY) == 0 )
+ curSel = (WORD)SendMessage( b->hWnd,
+ (UINT)b->type==B_LIST?LB_GETCURSEL:CB_GETCURSEL,
+ (WPARAM)0,
+ (DWORD)0L );
+ SendMessage( b->hWnd,
+ (UINT)b->type==B_LIST?LB_DELETESTRING:CB_DELETESTRING,
+ (WPARAM)inx,
+ (DWORD)0L );
+ inx = (wIndex_t)SendMessage( b->hWnd,
+ (UINT)b->type==B_LIST?LB_INSERTSTRING:CB_INSERTSTRING,
+ (WPARAM)inx,
+ (DWORD)(LPSTR)labelStr );
+ SendMessage( b->hWnd,
+ (UINT)b->type==B_LIST?LB_SETITEMDATA:CB_SETITEMDATA,
+ (WPARAM)inx,
+ (DWORD)ldp );
+ if ( (b->option&BL_MANY) == 0 && curSel == (WORD)inx)
+ SendMessage( b->hWnd,
+ (UINT)b->type==B_LIST?LB_SETCURSEL:CB_SETCURSEL,
+ (WPARAM)inx,
+ (DWORD)0L );
+ /*if (b->option&BL_ICON)*/
+ InvalidateRect( b->hWnd, NULL, FALSE );
+ return TRUE;
+}
+
+
+void wListDelete(
+ wList_p b,
+ wIndex_t inx )
+{
+ SendMessage( b->hWnd,
+ (UINT)b->type==B_LIST?LB_DELETESTRING:CB_DELETESTRING,
+ (WPARAM)inx,
+ (DWORD)0L );
+}
+
+
+wIndex_t wListGetCount(
+ wList_p bl )
+{
+ bl->count = (int)SendMessage( bl->hWnd, (UINT)bl->type==B_LIST?LB_GETCOUNT:CB_GETCOUNT, 0, 0L );
+ return bl->count;
+}
+
+
+void * wListGetItemContext(
+ wList_p bl,
+ wIndex_t inx )
+{
+ listData * ldp;
+ wListGetCount(bl);
+ if ( inx < 0 || inx >= bl->count ) return NULL;
+ ldp = (listData*)SendMessage( bl->hWnd,
+ (bl->type==B_LIST?LB_GETITEMDATA:CB_GETITEMDATA),
+ inx, 0L );
+ return ((ldp&&ldp!=(void*)LB_ERR)?ldp->itemContext:NULL);
+}
+
+
+wBool_t wListGetItemSelected(
+ wList_p bl,
+ wIndex_t inx )
+{
+ listData * ldp;
+ wListGetCount(bl);
+ if ( inx < 0 || inx >= bl->count ) return FALSE;
+ ldp = (listData*)SendMessage( bl->hWnd,
+ (bl->type==B_LIST?LB_GETITEMDATA:CB_GETITEMDATA),
+ inx, 0L );
+ return ((ldp&&ldp!=(void*)LB_ERR)?ldp->selected:FALSE);
+}
+
+
+wIndex_t wListGetSelectedCount(
+ wList_p bl )
+{
+ wIndex_t selcnt, inx;
+ wListGetCount(bl);
+ for ( selcnt=inx=0; inx<bl->count; inx++ )
+ if ( wListGetItemSelected( bl, inx ) )
+ selcnt++;
+ return selcnt;
+}
+
+
+wIndex_t wListAddValue(
+ wList_p b,
+ const char * value,
+ wIcon_p bm,
+ void * itemContext )
+{
+ int nindex;
+ listData * ldp;
+ ldp = (listData*)malloc( sizeof *ldp );
+ ldp->itemContext = itemContext;
+ ldp->bm = bm;
+ ldp->selected = FALSE;
+ if ( value == NULL )
+ value = "";
+ b->count++;
+ nindex = (int)SendMessage(
+ b->hWnd,
+ (UINT)b->type==B_LIST?LB_ADDSTRING:CB_ADDSTRING,
+ (WPARAM)0,
+ (DWORD)value );
+ if (nindex == 0) {
+ SendMessage( b->hWnd,
+ (UINT)b->type==B_LIST?LB_SETCURSEL:CB_SETCURSEL,
+ (WPARAM)nindex,
+ (DWORD)0 );
+ b->last = 0;
+ }
+ SendMessage( b->hWnd,
+ (UINT)b->type==B_LIST?LB_SETITEMDATA:CB_SETITEMDATA,
+ (WPARAM)nindex,
+ (DWORD)ldp );
+ return nindex;
+}
+
+
+int wListGetColumnWidths(
+ wList_p bl,
+ int colCnt,
+ wPos_t * colWidths )
+{
+ wIndex_t inx;
+
+ if ( bl->type != B_LIST )
+ return 0;
+ if ( bl->colWidths == NULL )
+ return 0;
+ for ( inx=0; inx<colCnt; inx++ ) {
+ if ( inx < bl->colCnt )
+ colWidths[inx] = bl->colWidths[inx];
+ else
+ colWidths[inx] = 0;
+ }
+ return bl->colCnt;
+}
+
+
+static void listSetBusy(
+ wControl_p b,
+ BOOL_T busy)
+{
+ wList_p bl = (wList_p)b;
+
+ EnableWindow( bl->hWnd, !(BOOL)busy );
+ if ( bl->hScrollWnd )
+ EnableWindow( bl->hScrollWnd, !(BOOL)busy );
+}
+
+static void listShow(
+ wControl_p b,
+ BOOL_T show)
+{
+ wList_p bl = (wList_p)b;
+
+ ShowWindow( bl->hWnd, show?SW_SHOW:SW_HIDE );
+ if ( bl->hScrollWnd && bl->maxWidth > bl->w )
+ ShowWindow( bl->hScrollWnd, show?SW_SHOW:SW_HIDE );
+#ifdef SHOW_DOES_SETFOCUS
+ if ( show && (bl->option&BO_READONLY)==0 )
+ hWnd = SetFocus( bl->hWnd );
+#endif
+}
+
+static void listSetPos(
+ wControl_p b,
+ wPos_t x,
+ wPos_t y )
+{
+ wList_p bl = (wList_p)b;
+ wPos_t x1, y1;
+ RECT rect;
+
+ bl->x = x1 = x;
+ bl->y = y1 = y;
+ if ( bl->colTitles )
+ y1 += listTitleHeight;
+ if (!SetWindowPos( b->hWnd, HWND_TOP, x1, y1,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ SWP_NOSIZE|SWP_NOZORDER))
+ mswFail("listSetPos");
+ if ( bl->hScrollWnd && bl->maxWidth > bl->w ) {
+ GetClientRect( bl->hWnd, &rect );
+ if (!SetWindowPos( bl->hScrollWnd, HWND_TOP, x1, y1+rect.bottom+2,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ SWP_NOSIZE|SWP_NOZORDER))
+ mswFail("listSetPos2");
+ }
+}
+
+
+static void listRepaintLabel(
+ HWND hWnd,
+ wControl_p b )
+{
+ wList_p bl = (wList_p)b;
+ HDC hDc;
+ RECT rc;
+ HFONT hFont;
+ HPEN hPen0, hPen1, hPen2, hPen3;
+ HBRUSH hBrush;
+ const char * * title;
+ int inx;
+ int start;
+ wPos_t colWidth;
+
+ mswRepaintLabel( hWnd, b );
+ if ( bl->colTitles == NULL )
+ return;
+ hDc = GetDC( hWnd );
+ start = bl->x-bl->scrollPos+2;
+ rc.top = bl->y;
+ rc.bottom = bl->y+listTitleHeight;
+ rc.left = bl->x-1;
+ rc.right = bl->x+bl->w;
+ hBrush = CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) );
+ FillRect( hDc, &rc, hBrush );
+ SetBkColor( hDc, GetSysColor( COLOR_BTNFACE ) );
+
+ hFont = SelectObject( hDc, mswLabelFont );
+ hPen1 = CreatePen( PS_SOLID, 0, GetSysColor( COLOR_BTNTEXT ) );
+ hPen2 = CreatePen( PS_SOLID, 0, GetSysColor( COLOR_BTNHIGHLIGHT ) );
+ hPen3 = CreatePen( PS_SOLID, 0, GetSysColor( COLOR_BTNSHADOW ) );
+ hPen0 = SelectObject( hDc, hPen1 );
+ MoveTo( hDc, rc.left, rc.top );
+ LineTo( hDc, rc.right, rc.top );
+ LineTo( hDc, rc.right, rc.bottom );
+ LineTo( hDc, rc.left, rc.bottom );
+ LineTo( hDc, rc.left, rc.top );
+ SelectObject( hDc, hPen2 );
+ MoveTo( hDc, rc.left+1, rc.bottom-1 );
+ LineTo( hDc, rc.left+1, rc.top+1 );
+ LineTo( hDc, rc.right-1, rc.top+1 );
+ SelectObject( hDc, hPen3 );
+ MoveTo( hDc, rc.left+2, rc.bottom-1 );
+ LineTo( hDc, rc.right-1, rc.bottom-1 );
+ LineTo( hDc, rc.right-1, rc.top+1 );
+ rc.top += 2;
+ rc.bottom -= 1;
+ for ( inx=0,title=bl->colTitles; inx<bl->colCnt&&*title&&start<bl->x+bl->w; inx++ ) {
+ colWidth = bl->colWidths[inx];
+ if ( start+colWidth >= 3 ) {
+ rc.left = start;
+ if ( rc.left < bl->x+2 )
+ rc.left = bl->x+2;
+ rc.right = start+colWidth;
+ if ( rc.right > bl->x+bl->w-1 )
+ rc.right = bl->x+bl->w-1;
+ ExtTextOut( hDc, start+1, rc.top+0,
+ ETO_CLIPPED|ETO_OPAQUE, &rc,
+ *title, strlen(*title), NULL );
+ if ( start-bl->x >= 3 ) {
+ SelectObject( hDc, hPen1 );
+ MoveTo( hDc, start-1, rc.top-1 );
+ LineTo( hDc, start-1, rc.bottom+3 );
+ SelectObject( hDc, hPen2 );
+ MoveTo( hDc, start, rc.top );
+ LineTo( hDc, start, rc.bottom+1 );
+ SelectObject( hDc, hPen3 );
+ MoveTo( hDc, start-2, rc.top );
+ LineTo( hDc, start-2, rc.bottom+1 );
+ }
+ }
+ title++;
+ start += colWidth;
+ }
+ SelectObject( hDc, hPen0 );
+ SelectObject( hDc, hFont );
+ DeleteObject( hBrush );
+ DeleteObject( hPen1 );
+ DeleteObject( hPen2 );
+ DeleteObject( hPen3 );
+}
+
+
+#ifdef LATER
+static void listHandleSelectionState( LPDRAWITEMSTRUCT lpdis, LPRECT rc )
+{
+ int oldROP;
+ oldROP = SetROP2( lpdis->hDC, R2_NOT );
+ Rectangle( lpdis->hDC, rc->left, rc->top, rc->right, rc->bottom );
+ SetROP2( lpdis->hDC, oldROP );
+ /*InvertRect( lpdis->hDC, rc );*/
+}
+#endif
+
+static void listHandleFocusState( LPDRAWITEMSTRUCT lpdis, LPRECT rc )
+{
+ DrawFocusRect( lpdis->hDC, rc );
+}
+
+
+LRESULT listProc(
+ wControl_p b,
+ HWND hWnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam )
+{
+ wList_p bl = (wList_p)b;
+ int cnt, inx, selected;
+ long len;
+ listData * ldp;
+ HDC hDc;
+ LPMEASUREITEMSTRUCT lpmis;
+ TEXTMETRIC tm;
+ LPDRAWITEMSTRUCT lpdis;
+ RECT rc, rc1;
+ char * cp0, * cp1;
+ wPos_t colWidth, x;
+ int nPos;
+ HFONT hFont;
+ HPEN hPen;
+ HBRUSH hBrush;
+ WPARAM notification;
+ COLORREF col;
+
+ if (bl) switch( message ) {
+
+ case WM_COMMAND:
+ notification = WCMD_PARAM_NOTF;
+ switch (bl->type) {
+ case B_LIST:
+ switch (notification) {
+ case LBN_SELCHANGE:
+ case LBN_DBLCLK:
+ if ( (bl->option&BL_DBLCLICK)!=0 ?
+ notification!=LBN_DBLCLK :
+ notification==LBN_DBLCLK )
+ break;
+ if ( (bl->option&BL_MANY) ) {
+ wListGetCount(bl);
+ for ( inx=0; inx<bl->count; inx++ ) {
+ ldp = (listData*)SendMessage( bl->hWnd, LB_GETITEMDATA, inx, 0L );
+ if ( ldp != NULL && ldp != (void*)LB_ERR ) {
+ selected = ((long)SendMessage( bl->hWnd, LB_GETSEL, inx, 0L ) != 0L );
+ if ( selected != ldp->selected ) {
+ ldp->selected = selected;
+ if ( selected ) {
+ bl->last = inx;
+ cnt = (int)SendMessage( bl->hWnd, LB_GETTEXT, bl->last, (DWORD)(LPSTR)mswTmpBuff );
+ mswTmpBuff[cnt] = '\0';
+ } else {
+ mswTmpBuff[0] = '\0';
+ }
+ if ( bl->action )
+ bl->action( inx, mswTmpBuff, selected?1:2, bl->data, ldp->itemContext );
+ if ( selected && bl->valueP )
+ *bl->valueP = bl->last;
+ }
+ }
+ }
+ } else {
+ bl->last = (int)SendMessage( bl->hWnd, LB_GETCURSEL, 0, 0L );
+ cnt = (int)SendMessage( bl->hWnd, LB_GETTEXT, bl->last,
+ (DWORD)(LPSTR)mswTmpBuff );
+ mswTmpBuff[cnt] = '\0';
+ if (bl->action) {
+ ldp = (listData*)SendMessage( bl->hWnd, LB_GETITEMDATA,
+ bl->last, 0L );
+ bl->action( bl->last, mswTmpBuff, 1, bl->data,
+ ((bl->last>=0&&ldp&&ldp!=(void*)LB_ERR)?ldp->itemContext:NULL) );
+ }
+ if (bl->valueP) {
+ *bl->valueP = bl->last;
+ }
+ }
+ break;
+
+ case LBN_KILLFOCUS:
+ if ( ( bl->option&BL_MANY ) == 0 &&
+ bl->last != (int)SendMessage( bl->hWnd, LB_GETCURSEL, 0, 0L ) )
+ (void)SendMessage( bl->hWnd, LB_SETCURSEL, bl->last, 0L );
+ break;
+ }
+ break;
+
+ case B_DROPLIST:
+ case B_COMBOLIST:
+ switch (notification) {
+ case CBN_SELCHANGE:
+ case CBN_DBLCLK:
+ if ( (bl->type == B_DROPLIST) ||
+ ( (bl->option&BL_DBLCLICK)!=0 ?
+ notification!=CBN_DBLCLK :
+ notification==CBN_DBLCLK) )
+ break;
+
+ case CBN_CLOSEUP:
+ bl->last = (int)SendMessage( bl->hWnd, CB_GETCURSEL, 0, 0L );
+ if (bl->last < 0)
+ break;
+ if (bl->action) {
+ cnt = (int)SendMessage( bl->hWnd, CB_GETLBTEXT, bl->last,
+ (DWORD)(LPSTR)mswTmpBuff );
+ ldp = (listData*)SendMessage( bl->hWnd, CB_GETITEMDATA,
+ bl->last, 0L );
+ mswTmpBuff[cnt] = '\0';
+ bl->action( bl->last, mswTmpBuff, 1, bl->data,
+ ((bl->last>=0&&ldp&&ldp!=(void*)LB_ERR)?ldp->itemContext:NULL) );
+ }
+ if (bl->valueP) {
+ *bl->valueP = bl->last;
+ }
+ mswAllowBalloonHelp = TRUE;
+ /*SendMessage( bl->bWnd, CB_SETCURSEL, bl->last, 0L );*/
+ break;
+
+ case CBN_KILLFOCUS:
+ inx = (int)SendMessage( bl->hWnd, CB_GETCURSEL, 0, 0L );
+ if ( bl->last != inx )
+ (void)SendMessage( bl->hWnd, CB_SETCURSEL, bl->last, 0L );
+ break;
+
+ case CBN_DROPDOWN:
+ mswAllowBalloonHelp = FALSE;
+ break;
+
+ case CBN_EDITCHANGE:
+ bl->last = -1;
+ if (bl->action) {
+ cnt = (int)SendMessage( bl->hWnd, WM_GETTEXT, sizeof mswTmpBuff,
+ (DWORD)(LPSTR)mswTmpBuff );
+ mswTmpBuff[cnt] = '\0';
+ bl->action( -1, mswTmpBuff, 1, bl->data, NULL );
+ }
+ break;
+ }
+ break;
+ }
+ break;
+
+ case WM_MEASUREITEM:
+ lpmis = (LPMEASUREITEMSTRUCT)lParam;
+ hDc = GetDC( hWnd );
+ if ( bl->type == B_LIST )
+ hFont = SelectObject( hDc, mswLabelFont );
+ GetTextMetrics( hDc, &tm );
+ lpmis->itemHeight = tm.tmHeight;
+ if ( bl->type == B_LIST )
+ SelectObject( hDc, hFont );
+ ReleaseDC( hWnd, hDc );
+ break;
+
+ case WM_DRAWITEM:
+ lpdis = (LPDRAWITEMSTRUCT)lParam;
+ if (lpdis->itemID == -1) {
+ listHandleFocusState(lpdis, &lpdis->rcItem);
+ return TRUE;
+ }
+ ldp = (listData*)SendMessage( bl->hWnd,
+ (bl->type==B_LIST?LB_GETITEMDATA:CB_GETITEMDATA),
+ lpdis->itemID, 0L );
+ rc = lpdis->rcItem;
+ if (lpdis->itemAction & (ODA_DRAWENTIRE|ODA_SELECT|ODA_FOCUS)) {
+ if( bl->type == B_LIST )
+ hFont = SelectObject( lpdis->hDC, mswLabelFont );
+ cnt = (int)SendMessage( lpdis->hwndItem,
+ (bl->type==B_LIST?LB_GETTEXT:CB_GETLBTEXT),
+ lpdis->itemID, (LONG)(LPSTR)mswTmpBuff );
+ mswTmpBuff[cnt] = '\0';
+ if ( lpdis->itemState & ODS_SELECTED ) {
+ SetTextColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHTTEXT ) );
+ SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) );
+ } else {
+ SetTextColor( lpdis->hDC, GetSysColor( COLOR_WINDOWTEXT ) );
+ SetBkColor( lpdis->hDC, GetSysColor( COLOR_WINDOW ) );
+ }
+ rc1 = rc;
+ rc1.left -= bl->scrollPos;
+ for ( inx=0,cp0=mswTmpBuff; inx<bl->colCnt&&cp0&&rc1.left<rc.right; inx++ ) {
+ if ( inx>=bl->colCnt-1 || (cp1=strchr(cp0,'\t')) == NULL ) {
+ len = strlen( cp0 );
+ cp1=cp0 + len; // JBB, to avoid an MSC error below where cp1 has not been defined.
+ } else {
+ len = cp1-cp0;
+ cp1 ++;
+ }
+ if ( bl->colWidths ) {
+ colWidth = bl->colWidths[inx];
+ } else {
+ colWidth = rc.right;
+ }
+ if ( inx == 0 && ldp && ldp!=(void*)LB_ERR && ldp->bm ) {
+ if (mswPalette) {
+ SelectPalette( lpdis->hDC, mswPalette, 0 );
+ cnt = RealizePalette( lpdis->hDC );
+ }
+ hPen = SelectObject( lpdis->hDC, CreatePen( PS_SOLID, 0, GetSysColor( COLOR_WINDOW ) ) );
+ hBrush = SelectObject( lpdis->hDC, CreateSolidBrush( GetSysColor( COLOR_WINDOW ) ) );
+ Rectangle( lpdis->hDC, rc1.left, rc1.top, rc1.right, rc1.bottom );
+ DeleteObject( SelectObject( lpdis->hDC, hPen ) );
+ DeleteObject( SelectObject( lpdis->hDC, hBrush ) );
+
+ col = RGB( (ldp->bm->colormap[ 1 ]).rgbRed,
+ (ldp->bm->colormap[ 1 ]).rgbGreen,
+ (ldp->bm->colormap[ 1 ]).rgbBlue );
+ mswDrawIcon( lpdis->hDC, rc1.left+2, rc.top+0, ldp->bm, 0, col, col);
+
+ rc1.left += ldp->bm->w+6;
+ colWidth -= ldp->bm->w+6;
+ }
+ if ( inx>=bl->colCnt-1 || (rc1.right = rc1.left + colWidth) > rc.right )
+ rc1.right = rc.right;
+ if ( rc1.right > 0 && rc1.left+3 < rc.right ) {
+ ExtTextOut( lpdis->hDC, rc1.left+3, rc1.top+1,
+ ETO_CLIPPED | ETO_OPAQUE, &rc1,
+ (LPSTR)cp0, (int)len, NULL );
+ }
+ rc1.left = rc1.right;
+ cp0 = cp1;
+ }
+ if ( lpdis->itemState & ODS_SELECTED ) {
+ SetTextColor( lpdis->hDC, GetSysColor( COLOR_WINDOWTEXT ) );
+ SetBkColor( lpdis->hDC, GetSysColor( COLOR_WINDOW ) );
+ }
+ if (lpdis->itemState & ODS_FOCUS) {
+ DrawFocusRect( lpdis->hDC, &rc );
+ }
+ if ( bl->type == B_LIST)
+ SelectObject( lpdis->hDC, hFont );
+ return TRUE;
+ }
+
+ break;
+
+ case WM_HSCROLL:
+ len = ((long)bl->maxWidth)-((long)bl->w);
+ if ( len <= 0 )
+ return 0;
+ switch ( WSCROLL_PARAM_CODE ) {
+ case SB_LEFT:
+ if ( bl->scrollPos == 0 )
+ return 0;
+ bl->scrollPos = 0;
+ break;
+ case SB_LINELEFT:
+ case SB_PAGELEFT:
+ if ( bl->scrollPos == 0 )
+ return 0;
+ for ( inx=colWidth=0; inx<bl->colCnt; inx++ ) {
+ if ( colWidth+bl->colWidths[inx] >= bl->scrollPos ) {
+ bl->scrollPos = colWidth;
+ break;
+ }
+ colWidth += bl->colWidths[inx];
+ }
+ break;
+ case SB_LINERIGHT:
+ case SB_PAGERIGHT:
+ if ( bl->scrollPos >= len )
+ return 0;
+ for ( inx=colWidth=0; inx<bl->colCnt; inx++ ) {
+ if ( colWidth >= bl->scrollPos ) {
+ bl->scrollPos = colWidth+bl->colWidths[inx];
+ break;
+ }
+ colWidth += bl->colWidths[inx];
+ }
+ break;
+ case SB_RIGHT:
+ if ( bl->scrollPos >= len )
+ return 0;
+ bl->scrollPos = (int)len;
+ break;
+ case SB_THUMBTRACK:
+ return 0;
+ case SB_THUMBPOSITION:
+ nPos = (int)WSCROLL_PARAM_NPOS;
+ bl->scrollPos = (int)(len*nPos/100);
+ break;
+ case SB_ENDSCROLL:
+ return 0;
+ }
+ if ( bl->scrollPos > len ) bl->scrollPos = (int)len;
+ if ( bl->scrollPos < 0 ) bl->scrollPos = 0;
+ nPos = (int)(((long)bl->scrollPos)*100L/len+0.5);
+ SetScrollPos( bl->hScrollWnd, SB_CTL, nPos, TRUE );
+ InvalidateRect( bl->hWnd, NULL, FALSE );
+ listRepaintLabel( ((wControl_p)(bl->parent))->hWnd, (wControl_p)bl );
+ return 0;
+
+ case WM_LBUTTONDOWN:
+ if ( bl->type != B_LIST )
+ break;
+ if ( bl->colCnt <= 1 )
+ break;
+ x = bl->dragPos = LOWORD(lParam)+bl->scrollPos-4;
+ bl->dragCol = -1;
+ for ( inx=0; inx<bl->colCnt; inx++ ) {
+ x -= bl->colWidths[inx];
+ if ( x < -5 ) break;
+ if ( x <= 0 ) { bl->dragCol = inx; break; }
+ if ( x > bl->colWidths[inx+1] ) continue;
+ if ( x <= 10 ) { bl->dragCol = inx; break; }
+ }
+ if ( bl->dragCol >= 0 )
+ bl->dragColWidth = bl->colWidths[inx];
+ return 0L;
+
+#ifdef LATER
+ case WM_MOUSEMOVE:
+ if ( (wParam&MK_LBUTTON) == 0 )
+ break;
+ if ( bl->type != B_LIST )
+ break;
+ if ( bl->colCnt <= 1 )
+ break;
+ x = LOWORD(lParam)+bl->scrolPos;
+ for ( inx=0; inx<bl->colCnt; inx++ ) {
+ x -= bl->colWidths[inx];
+ if ( x <= 0 )
+ break;
+ }
+ return 0L;
+#endif
+
+ case WM_MOUSEMOVE:
+ if ( (wParam&MK_LBUTTON) == 0 )
+ break;
+ case WM_LBUTTONUP:
+ if ( bl->type != B_LIST )
+ break;
+ if ( bl->colCnt <= 1 )
+ break;
+ if ( bl->dragCol < 0 )
+ break;
+ x = LOWORD(lParam)+bl->scrollPos-4-bl->dragPos; /* WIN32??? */
+ bl->colWidths[bl->dragCol] = bl->dragColWidth+x;
+ if ( bl->colWidths[bl->dragCol] < 0 )
+ bl->colWidths[bl->dragCol] = 0;
+ for ( bl->maxWidth=inx=0; inx<bl->colCnt; inx++ )
+ bl->maxWidth += bl->colWidths[inx];
+ if ( bl->maxWidth <= bl->w ) {
+ x = bl->w - bl->maxWidth;
+ bl->colWidths[bl->colCnt-1] += x;
+ bl->maxWidth = bl->w;
+ bl->scrollPos = 0;
+ } else {
+ if ( bl->scrollPos+bl->w > bl->maxWidth ) {
+ bl->scrollPos = bl->maxWidth - bl->w;
+ }
+ }
+ InvalidateRect( bl->hWnd, NULL, FALSE );
+ listRepaintLabel( ((wControl_p)(bl->parent))->hWnd, (wControl_p)bl );
+ return 0L;
+
+ }
+
+ return DefWindowProc( hWnd, message, wParam, lParam );
+}
+
+long FAR PASCAL _export pushList(
+ HWND hWnd,
+ UINT message,
+ UINT wParam,
+ LONG lParam )
+{
+ /* Catch <Return> and cause focus to leave control */
+#ifdef WIN32
+ long inx = GetWindowLong( hWnd, GWL_ID );
+#else
+ short inx = GetWindowWord( hWnd, GWW_ID );
+#endif
+ wControl_p b = mswMapIndex( inx );
+
+ switch (message) {
+ case WM_CHAR:
+ if ( b != NULL) {
+ switch( WCMD_PARAM_ID ) {
+ case 0x0D:
+ case 0x1B:
+ case 0x09:
+ SetFocus( ((wControl_p)(b->parent))->hWnd );
+ SendMessage( ((wControl_p)(b->parent))->hWnd, WM_CHAR,
+ wParam, lParam );
+ /*SendMessage( ((wControl_p)(b->parent))->hWnd, WM_COMMAND,
+ inx, MAKELONG( hWnd, EN_KILLFOCUS ) );*/
+ return 0L;
+ }
+ }
+ break;
+ }
+ return CallWindowProc( oldListProc, hWnd, message, wParam, lParam );
+}
+
+long FAR PASCAL _export pushCombo(
+ HWND hWnd,
+ UINT message,
+ UINT wParam,
+ LONG lParam )
+{
+ /* Catch <Return> and cause focus to leave control */
+#ifdef WIN32
+ long inx = GetWindowLong( hWnd, GWL_ID );
+#else
+ short inx = GetWindowWord( hWnd, GWW_ID );
+#endif
+ wControl_p b = mswMapIndex( inx );
+
+ switch (message) {
+ case WM_CHAR:
+ if ( b != NULL) {
+ switch( WCMD_PARAM_ID ) {
+ case 0x0D:
+ case 0x1B:
+ case 0x09:
+ SetFocus( ((wControl_p)(b->parent))->hWnd );
+ SendMessage( ((wControl_p)(b->parent))->hWnd, WM_CHAR,
+ wParam, lParam );
+ /*SendMessage( ((wControl_p)(b->parent))->hWnd, WM_COMMAND,
+ inx, MAKELONG( hWnd, EN_KILLFOCUS ) );*/
+ return 0L;
+ }
+ }
+ break;
+ }
+ return CallWindowProc( oldComboProc, hWnd, message, wParam, lParam );
+}
+
+static callBacks_t listCallBacks = {
+ listRepaintLabel,
+ NULL,
+ listProc,
+ listSetBusy,
+ listShow,
+ listSetPos };
+
+
+static wList_p listCreate(
+ int typ,
+ const char *className,
+ long style,
+ wWin_p parent,
+ POS_T x,
+ POS_T y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ long number,
+ POS_T width,
+ long *valueP,
+ wListCallBack_p action,
+ void *data,
+ wBool_t addFocus,
+ int *indexR )
+{
+ wList_p b;
+ RECT rect;
+ int index;
+
+ b = (wList_p)mswAlloc( parent, typ, mswStrdup(labelStr), sizeof *b, data, &index );
+ mswComputePos( (wControl_p)b, x, y );
+ b->option = option;
+ b->count = 0;
+ b->last = -1;
+ b->valueP = valueP;
+ b->labelY += 4;
+ b->action = action;
+ b->maxWidth = 0;
+ b->scrollPos = 0;
+ b->scrollH = 0;
+ b->dragPos = 0;
+ b->dragCol = -1;
+
+ b->hWnd = CreateWindow( className, NULL,
+ style | WS_CHILD | WS_VISIBLE | mswGetBaseStyle(parent), b->x, b->y,
+ width, LIST_HEIGHT*(int)number,
+ ((wControl_p)parent)->hWnd, (HMENU)index, mswHInst, NULL );
+ if (b->hWnd == NULL) {
+ mswFail("CreateWindow(LIST)");
+ return b;
+ }
+
+#ifdef CONTROL3D
+ Ctl3dSubclassCtl( b->hWnd );
+#endif
+
+ GetWindowRect( b->hWnd, &rect );
+ b->w = rect.right - rect.left;
+ b->h = rect.bottom - rect.top;
+ b->colCnt = 1;
+ b->colWidths = NULL;
+ b->colTitles = NULL;
+
+ mswAddButton( (wControl_p)b, TRUE, helpStr );
+ mswCallBacks[typ] = &listCallBacks;
+ if (addFocus) {
+ mswChainFocus( (wControl_p)b );
+ if (b->type == B_LIST) {
+ newListProc = MakeProcInstance( (XWNDPROC)pushList, mswHInst );
+ oldListProc = (XWNDPROC)GetWindowLong( b->hWnd, GWL_WNDPROC );
+ SetWindowLong( b->hWnd, GWL_WNDPROC, (LONG)newListProc );
+ } else {
+ newComboProc = MakeProcInstance( (XWNDPROC)pushCombo, mswHInst );
+ oldComboProc = (XWNDPROC)GetWindowLong( b->hWnd, GWL_WNDPROC );
+ SetWindowLong( b->hWnd, GWL_WNDPROC, (LONG)newComboProc );
+ }
+ }
+ if ( indexR )
+ *indexR = index;
+ if ( !mswThickFont )
+ SendMessage( b->hWnd, WM_SETFONT, (WPARAM)mswLabelFont, 0L );
+ return b;
+}
+
+
+wList_p wListCreate(
+ wWin_p parent,
+ POS_T x,
+ POS_T y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ long number,
+ POS_T width,
+ int colCnt,
+ wPos_t * colWidths,
+ wBool_t * colRightJust,
+ const char * * colTitles,
+ long *valueP,
+ wListCallBack_p action,
+ void *data )
+{
+ long bs;
+ wList_p bl;
+ static int dbu = 0;
+ RECT rect;
+ int index;
+ int i;
+
+ bs = LBS_NOTIFY | WS_VSCROLL | WS_BORDER | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS;
+ if (option & BL_MANY)
+ bs |= LBS_MULTIPLESEL|LBS_EXTENDEDSEL;
+ if (option & BL_SORT)
+ bs |= LBS_SORT;
+ if ( colCnt > 1 )
+ bs |= WS_HSCROLL;
+ if ( colTitles ) {
+ y += listTitleHeight;
+ number -= 1;
+ }
+ bl = listCreate( B_LIST, "LISTBOX", bs, parent, x, y, helpStr,
+ labelStr, option, number, width, valueP, action, data, TRUE, &index );
+ if ( colTitles ) {
+ bl->y -= listTitleHeight;
+ bl->h += listTitleHeight;
+ }
+ if ( colCnt > 1 ) {
+ bl->colCnt = colCnt;
+ bl->colWidths = (int*)malloc( colCnt * sizeof *bl->colWidths );
+ bl->colRightJust = (wBool_t*)malloc( colCnt * sizeof *bl->colRightJust );
+ bl->colTitles = colTitles;
+ bl->maxWidth = 0;
+ memcpy( bl->colWidths, colWidths, colCnt * sizeof *bl->colWidths );
+ for ( i=0; i<colCnt; i++ ) {
+ bl->colWidths[i] = colWidths[i];
+ bl->maxWidth += bl->colWidths[i];
+ }
+ bl->hScrollWnd = CreateWindow( "ScrollBar", NULL,
+ SBS_HORZ | SBS_BOTTOMALIGN | WS_CHILD | WS_VISIBLE | mswGetBaseStyle(parent), bl->x, bl->y,
+ width, CW_USEDEFAULT,
+ ((wControl_p)parent)->hWnd, (HMENU)index, mswHInst, NULL );
+ if (bl->hScrollWnd == NULL)
+ mswFail("CreateWindow(LISTSCROLL)");
+ SetScrollRange( bl->hScrollWnd, SB_CTL, 0, 100, TRUE );
+ GetWindowRect( bl->hScrollWnd, &rect );
+ bl->scrollH = rect.bottom - rect.top+2;
+ }
+ return bl;
+}
+
+
+wList_p wDropListCreate(
+ wWin_p parent,
+ POS_T x,
+ POS_T y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ long number,
+ POS_T width,
+ long *valueP,
+ wListCallBack_p action,
+ void *data )
+{
+ long bs;
+
+ if ( (option&BL_EDITABLE) != 0 )
+ bs = CBS_DROPDOWN;
+ else
+ bs = CBS_DROPDOWNLIST;
+ bs |= WS_VSCROLL | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS;
+ if (option & BL_SORT)
+ bs |= CBS_SORT;
+ return listCreate( B_DROPLIST, "COMBOBOX", bs, parent, x, y, helpStr,
+ labelStr, option, number, width, valueP, action, data, TRUE, NULL );
+}
+
+wList_p wComboListCreate(
+ wWin_p parent,
+ POS_T x,
+ POS_T y,
+ const char * helpStr,
+ const char * labelStr,
+ long option,
+ long number,
+ POS_T width,
+ long *valueP,
+ wListCallBack_p action,
+ void *data )
+{
+ long bs;
+
+ bs = CBS_SIMPLE | WS_VSCROLL | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS;
+ if (option & BL_SORT)
+ bs |= CBS_SORT;
+ return listCreate( B_COMBOLIST, "COMBOBOX", bs, parent, x, y, helpStr,
+ labelStr, option, number, width, valueP, action, data, FALSE, NULL );
+}