📄 combobox.c
字号:
/*--------------------------------------------------------------------------** ComboBox.c Twin From: Twin/controls**** **------------------------- < License Information > ------------------------**** This file was originally a part of Willows TWIN. Willows** TWIN was released under a Library GPL (LGPL). This permits** redistribution of this source code, provided that the full** TWIN license is in effect, and provided that all modifications** to this source code are made publicly available.** Please refer to Willows software (www.willows.com) or** LICENSE for full information.** ** Under Twine, this file is also protected by an LGPL. Please** see LICENSE for full details on this license.** **** Copyright 1997 Willows Software, Inc. **------------------------ < File Content Description > --------------------**** Module: controls/ComboBox.c**** Description:** **** Functions defined:** **------------------------- < Revision Information > -----------------------**** Full Revision history at bottom of file** **--------------------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "windows.h"#include "windowsx.h"#define WinMalloc(n) malloc((n))#define WinFree(p) free(p)#define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)#define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)#define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)#define GET_WM_COMMAND_MPS(id, hwnd, cmd) \ (WPARAM)MAKELONG(id, cmd), (LONG)(hwnd)#define LOSHORT(x) (short int)LOWORD(x)#define Edit_SetSel(hwndCtl, ichStart, ichEnd) ((void)SendMessage((hwndCtl), EM_SETSEL, (ichStart), (ichEnd)))typedef struct { HFONT hFont; /* hFont used */ HWND hWndParent; /* parent window */ UINT nID; /* control ID */ WORD wStateFlags; /* combobox state flags */ UINT wStyle; /* this is a copy of LOWORD(style) */ BOOL bExtended; /* extended UI flag */ BOOL bRedraw; /* MiD - redraw flag, draw only if it's 1 */ HWND EditControl; /* edit/static control hWnd */ HWND ListBoxControl; /* listbox control hWnd */ RECT ButtonRect; /* local button rect (client) */ RECT ListBoxRect; /* listbox rect (screen) */ UINT uHeight; /* height of the normal state */ WNDPROC lpfnOldStatic; /* previous static wndproc */ UINT nListItems; /* ecw */} COMBOBOX;#define CWD_LPCBDATA 0#define CBC_EDITID 1#define CSF_CAPTUREACTIVE 0x0001#define CSF_LOCALBUTTONDOWN 0x0002#define CSF_BUTTONDOWN 0x0004#define CSF_LBOXBUTTONDOWN 0x0008#define CSF_FOCUS 0x0010 /* MiD */#define CSF_HASDROPPED 0x0020 /* weav */#define SET_STATE(lp, wMask) (lp->wStateFlags |= (wMask))#define CLEAR_STATE(lp, wMask) (lp->wStateFlags &= ~(wMask))#define IS_SET(lp, wMask) (lp->wStateFlags & (wMask))#define BOWNERDRAW(l) ((l)->wStyle & (CBS_OWNERDRAWFIXED|CBS_OWNERDRAWVARIABLE))/********************************************** Styles: CBS_AUTOHSCROLL passed to the edit control CBS_DISABLENOSCROLL passed to the listbox control CBS_DROPDOWN CBS_DROPDOWNLIST CBS_HASSTRINGS passed to the listbox control CBS_NOINTEGRALHEIGHT passed to the listbox control CBS_OEMCONVERT passed to the edit control CBS_OWNERDRAWFIXED passed to the listbox control CBS_OWNERDRAWVARIABLE passed to the listbox control CBS_SIMPLE TODO CBS_SORT passed to the listbox control WS_VSCROLL passed to the listbox control*********************************************//********************************************** CBN_xxx messages to be added from mouse tracking... CBN_SELENDCANCEL TODO CBN_SELENDOK TODO*********************************************//* imported stuff */#if 1voidDraw3DButtonRect(HDC hDC, HPEN hPenHigh, HPEN hPenShadow, RECT rc, BOOL fClicked){ HPEN hPenOld; POINT lpt[6]; POINT p3[3]; int shrink=1; hPenOld = SelectObject(hDC, hPenShadow); if (fClicked) { lpt[0].x = lpt[1].x = rc.left; lpt[1].y = lpt[2].y = rc.top; lpt[2].x = rc.right-1; lpt[0].y = rc.bottom-1; Polyline(hDC,lpt,3); } else { lpt[0].x = lpt[1].x = rc.right-1; lpt[0].y = rc.top; lpt[1].y = lpt[2].y = rc.bottom-1; lpt[2].x = rc.left; lpt[3].x = rc.left+1; lpt[3].y = lpt[4].y = rc.bottom-2; lpt[4].x = lpt[5].x = rc.right-2; lpt[5].y = rc.top+1; Polyline(hDC,lpt,6); SelectObject(hDC, hPenHigh); lpt[0].x = rc.right-1; lpt[0].y = lpt[1].y = rc.top; lpt[1].x = lpt[2].x = rc.left; lpt[2].y = rc.bottom-1; lpt[3].x = lpt[4].x = rc.left+1; lpt[3].y = rc.bottom-2; lpt[4].y = lpt[5].y = rc.top+1; lpt[5].x = rc.right-2; Polyline(hDC,lpt,6); } SelectObject(hDC,GetStockObject(BLACK_BRUSH)); /* down */ p3[0].x= rc.left + ((rc.right-rc.left)/2) - 1; p3[0].y= rc.bottom - 4 - shrink; p3[1].x= rc.left + 2 + shrink - 1; p3[1].y= rc.bottom-(rc.bottom-rc.top) + 2 + shrink; p3[2].x= rc.left + ((rc.right-rc.left)-4) - shrink; p3[2].y= rc.bottom-(rc.bottom-rc.top) + 2 + shrink; Polygon(hDC,p3,3); SelectObject(hDC,hPenOld);}#endif#if 0 /* jmt: fix: no COMBOLBOX */extern LRESULT DefLISTBOXProc(HWND, UINT, WPARAM, LPARAM);extern LRESULT ListboxCtrlProc(HWND, UINT, WPARAM, LPARAM);#endif#if 0static HPEN GetSysColorPen(int color){ return NULL;}static HBRUSH GetSysColorBrush(int color){ return NULL;}#endiftypedef HWND HWND32;#if 0 /* jmt: fix: no ownerdraw */typedef HANDLE HCLASS32;static HCLASS32 FindClass(LPCSTR str, HINSTANCE hInstance){ return NULL;}#endif#if 0 /* jmt: fix: no scrollbar */static HWND TWIN_ConvertToSysScroll(HWND hwnd, BOOL status, LPPOINT pp){ return NULL;}#endifextern HWND listwp;static HWND WindowFromPoint(POINT pt){ HWND wp,wp1; int dx,dy,dx1,dy1;#if 0 return NULL; /* fix!! */#else wp1=NULL; switch(sizeof(dx)) { case 4: dx=0x7fffffff; dy=0x7fffffff; break; case 2: dx=0x7fff; dy=0x7fff; break; } for(wp=listwp; wp; wp=wp->next) { if (wp->winrect.left <= pt.x && pt.x <= wp->winrect.right) { dx1=(wp->winrect.right-pt.x); if (dx1<dx) { wp1=wp; dx=dx1; } dx1=(pt.x-wp->winrect.left); if (dx1<dx) { wp1=wp; dx=dx1; } } if (wp->winrect.top <= pt.y && pt.y <= wp->winrect.bottom) { dy1=(wp->winrect.bottom-pt.y); if (dy1<dy) { wp1=wp; dy=dy1; } dy1=(pt.y-wp->winrect.top); if (dy1<dy) { wp1=wp; dy=dy1; } } }#endif return wp1;}/* internal stuff */static void CBoxDrawButton(HWND,UINT,COMBOBOX *);static void CBoxSendMouseToLBox(COMBOBOX *, UINT, WPARAM, POINT);static void CBoxCapture(HWND, WORD);static void CBoxDrawEdit(COMBOBOX *, HWND, UINT);static void CBoxDrawStatic(COMBOBOX *, HWND, UINT); /* MiD *//* handle specific CB messages */static LRESULT DefCBProc(HWND , UINT , WPARAM , LPARAM );#if 0 /* jmt: fix: no ownerdraw */static WNDPROC lpComboBinToNat = 0;#endifstatic LRESULT CALLBACK DefComboboxProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);int WINAPI MwRegisterComboboxControl(HINSTANCE hInstance){ WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; wc.lpfnWndProc = (WNDPROC)DefComboboxProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = 0; wc.hbrBackground= GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName= "COMBOBOX"; return RegisterClass(&wc);}static LRESULT CALLBACK DefComboboxProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ PAINTSTRUCT ps; HDC hDC; TEXTMETRIC tm;#if 0 /* jmt: fix: no ownerdraw */ MEASUREITEMSTRUCT mis;#endif COMBOBOX *lp = (COMBOBOX *)NULL; LRESULT rc; HINSTANCE hInst; POINT cp,cpScreen,pp; UINT uiKey; LPCREATESTRUCT lpcs;#if 1 /* jmt: fix: no WM_WINDOWPOSCHANGING */ LPWINDOWPOS lpwp;#endif#if 0 /* jmt: fix: no ownerdraw */ HCLASS32 hComboClass32; LPMEASUREITEMSTRUCT lpmis; LPDRAWITEMSTRUCT lpdis; LPDELETEITEMSTRUCT lpdlis;#endif DWORD dwStyle,dwExStyle; WORD wEditWidth = 0,wEditHeight; WORD wCBN;#if 0 /* jmt: fix: no WM_SETFONT/WM_GETFONT */ RECT rcClient;#endif rc = CB_OKAY; if ((uMsg != WM_CREATE/*WM_NCCREATE*/) && /*(uMsg != WM_CONVERT) &&*/ !(lp = (COMBOBOX *)hWnd->userdata/*GetWindowLong(hWnd,CWD_LPCBDATA)*/)) return rc; switch(uMsg) {#if 0 case WM_SIZE: case WM_ENABLE: case WM_LBUTTONDBLCLK: case WM_COMPAREITEM: case WM_CUT: case WM_CLEAR:#endif case WM_SETFOCUS: SET_STATE(lp, CSF_FOCUS); if ((lp->wStyle & 0x0F) == CBS_DROPDOWNLIST) { uiKey = (UINT)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0L); CBoxDrawStatic(lp, hWnd, uiKey); } if (lp->EditControl) { SetFocus(lp->EditControl); } break; case WM_KILLFOCUS: CLEAR_STATE(lp, CSF_FOCUS); if ((lp->wStyle & 0x0F) == CBS_DROPDOWNLIST) { uiKey = (UINT)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0L); CBoxDrawStatic(lp, hWnd, uiKey); } /* ** Hide listbox when loosing focus to window other than ** our own listbox... When wParam == 0 we "loose" the focus ** to the scrollbar in a listbox! */ if ((lp->wStyle & 0x0F) != CBS_SIMPLE && wParam != (WPARAM)lp->ListBoxControl && wParam != 0) SendMessage(hWnd, CB_SHOWDROPDOWN, 0, 0L); fprintf(stderr," 385: WM_KILLFOCUS\n"); break;#if 0 /* jmt: fix: no WM_KEYDOWN */ case WM_KEYDOWN: /* MiD 08/14/95 */ /* ** We have to process this message in order to show ** current selection in a static control for certain ** keys. This doesn't affect combobox with an edit ** control, since the edit traps all key messages. */ { int nCur = SendMessage(lp->ListBoxControl, LB_GETCURSEL,0, 0L); int nPrevCur = nCur; int nCount = SendMessage(lp->ListBoxControl, LB_GETCOUNT, 0, 0L); if (nCount == 0) break; switch(wParam) { case VK_HOME: nCur = 0; break; case VK_END: nCur = nCount - 1; break; case VK_UP: nCur--; break; case VK_DOWN: nCur++; break; default: return 0L; } if (nCur >= nCount) nCur = nCount - 1; if (nCur < 0) nCur = 0; SendMessage(lp->ListBoxControl, LB_SETCURSEL, nCur, 0L); SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID, hWnd, CBN_SELCHANGE)); if (nCur != nPrevCur)/* ecw */ SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID, hWnd, CBN_SELENDOK)); InvalidateRect(hWnd, NULL, 1); break; }#endif /* WM_KEYDOWN */ case WM_CHAR: { int nNewCur; int nOldCur; if (lp->EditControl) { SendMessage(lp->EditControl, uMsg, wParam, lParam); } else { nOldCur = SendMessage(lp->ListBoxControl, LB_GETCURSEL,0, 0L); SendMessage(lp->ListBoxControl, uMsg, wParam, lParam); nNewCur = SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0L); if (nNewCur != nOldCur) { SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID, hWnd, CBN_SELCHANGE)); InvalidateRect(hWnd, NULL, 1); } } break; }#if 0 /* jmt: fix: no WM_SETREDRAW */ case WM_SETREDRAW: lp->bRedraw = wParam; if (lp->EditControl)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -