📄 combobox.c
字号:
/*
** 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)
SendMessage(lp->EditControl, WM_SETREDRAW, wParam, lParam);
if (lp->ListBoxControl)
SendMessage(lp->ListBoxControl, WM_SETREDRAW, wParam, lParam);
break;
#endif
case WM_CREATE: /*WM_NCCREATE:*/
lp = (COMBOBOX *)GdMalloc(sizeof(COMBOBOX));
memset((LPSTR)lp,'\0',sizeof(COMBOBOX));
/* save ptr to internal structure */
hWnd->userdata=(DWORD)lp; /* -SetWindowLong(hWnd, CWD_LPCBDATA, (LONG) lp); */
/* this is for CreateWindow calls */
hInst = NULL; /* -GetWindowInstance(hWnd); */
/* fill in the internal structure */
lpcs = (LPCREATESTRUCT)lParam;
lp->bRedraw = 1;
lp->wStateFlags = 0;
lp->wStyle = (UINT)LOWORD(lpcs->style);
if (!BOWNERDRAW(lp))
lp->wStyle |= CBS_HASSTRINGS;
lp->bExtended = TRUE;
lp->hFont = 0;
lp->hWndParent = lpcs->hwndParent;
lp->nID = (UINT)lpcs->hMenu;
#if 0 /* jmt: fix: no ownerdraw */
/* calc the height of the edit/static control */
if (0) /* (BOWNERDRAW(lp)) */
{
mis.CtlType = ODT_COMBOBOX;
mis.CtlID = (UINT)lpcs->hMenu;
mis.itemID = (UINT)-1;
mis.itemData = 0L;
SendMessage(lpcs->hwndParent, WM_MEASUREITEM, (WPARAM)lpcs->hMenu, (LPARAM)&mis);
/* * wEditHeight = (WORD)mis.itemHeight + 2; ***/
}
#endif /* ownerdraw */
/* get system font dimensions */
hDC = GetDC((HWND)0);
GetTextMetrics(hDC,&tm);
ReleaseDC((HWND)0,hDC);
/* allow different fonts to fit, don't hard code */
/* otherwise big fonts won't fit. */
/* ***wEditHeight = ((tm.tmHeight - tm.tmInternalLeading)*7)/4;*****/
wEditHeight = tm.tmHeight + tm.tmInternalLeading * 3;
lp->uHeight = (UINT)wEditHeight;
if ((lp->wStyle & 0x0F) != CBS_SIMPLE)
{
lp->ButtonRect.top = 0;
lp->ButtonRect.left = lpcs->cx - 1 - GetSystemMetrics(SM_CXVSCROLL);
lp->ButtonRect.right = lpcs->cx;
lp->ButtonRect.bottom = wEditHeight;
/* for CBS_DROPDOWN/DROPDOWNLIST resize the window */
SetWindowPos(hWnd, 0,
0, 0, lpcs->cx, (int)wEditHeight,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW);
}
else SetRectEmpty(&lp->ButtonRect);
if ((lp->wStyle & 0xf) != CBS_DROPDOWNLIST)
{ /* EDIT field - calc edit control style */
dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER;
if (lp->wStyle & CBS_AUTOHSCROLL)
dwStyle |= ES_AUTOHSCROLL;
if (lp->wStyle & CBS_OEMCONVERT)
dwStyle |= ES_OEMCONVERT;
if ((lp->wStyle & 0x0F) == CBS_SIMPLE)
{
fprintf(stderr," 528: wEditWidth = lpcs->cx=%d\n",lpcs->cx);
wEditWidth = lpcs->cx;
}
else /* ?if ((lp->wStyle & 0xf) == CBS_DROPDOWN) */
{
fprintf(stderr," 533: wEditWidth = lp->ButtonRect.left - 5=%d;\n",lp->ButtonRect.left - 5);
wEditWidth = lp->ButtonRect.left - 5;
}
/* create edit control */
lp->EditControl = CreateWindow("EDIT", NULL, dwStyle,
0, 0, wEditWidth, wEditHeight,
hWnd, (HMENU)CBC_EDITID,
hInst,(LPVOID)NULL);
}
else /* CBS_DROPDOWN -- static instead of edit */
lp->EditControl = 0;
/* listbox style */
/* jmt: fix: no WS_EX_SAVEBITS, WS_EX_NOCAPTURE, WS_EX_POPUPMENU */
dwExStyle = 0L; /* WS_EX_SAVEBITS | WS_EX_NOCAPTURE | WS_EX_POPUPMENU; */
dwStyle = WS_BORDER | LBS_NOTIFY ; /* | LBS_COMBOLBOX; */
if ((lp->wStyle & 0xf) == CBS_SIMPLE)
dwStyle |= WS_VISIBLE | WS_CHILD;
else
dwStyle |= WS_POPUP;
#if 0
if (lp->wStyle & CBS_DISABLENOSCROLL)
dwStyle |= LBS_DISABLENOSCROLL;
#endif
if (lp->wStyle & CBS_HASSTRINGS)
dwStyle |= LBS_HASSTRINGS;
if (lp->wStyle & CBS_NOINTEGRALHEIGHT)
dwStyle |= LBS_NOINTEGRALHEIGHT;
if (lp->wStyle & CBS_OWNERDRAWFIXED)
dwStyle |= LBS_OWNERDRAWFIXED;
if (lp->wStyle & CBS_OWNERDRAWVARIABLE)
dwStyle |= LBS_OWNERDRAWVARIABLE;
if (lp->wStyle & CBS_SORT)
dwStyle |= LBS_SORT;
if (lpcs->style & WS_VSCROLL)
dwStyle |= WS_VSCROLL;
/* calc listbox dimensions and position */
if ((lp->wStyle & 0xf) == CBS_SIMPLE) {
lp->ListBoxRect.left = 5;
lp->ListBoxRect.top = wEditHeight - 1;
lp->ListBoxRect.right = lpcs->cx;
lp->ListBoxRect.bottom = lpcs->cy - 2;
} else {
lp->ListBoxRect.left = lpcs->x;
lp->ListBoxRect.right = lp->ListBoxRect.left + lpcs->cx - 1;
lp->ListBoxRect.top = lpcs->y + wEditHeight - 1;
lp->ListBoxRect.bottom = lp->ListBoxRect.top + lpcs->cy + 1;
if ((lp->wStyle & 0x0F) == CBS_DROPDOWN) {
lp->ListBoxRect.left += 5;
}
}
#ifdef LATER
cp.x = ((lp->wStyle & 0xf) == CBS_DROPDOWNLIST)?0:5;
cp.y = wEditHeight - 1;
if ((lp->wStyle & 0xf) != CBS_SIMPLE)
ClientToScreen(hWnd,&cp);
lp->ListBoxRect.left = cp.x;
lp->ListBoxRect.top = cp.y;
lp->ListBoxRect.right = cp.x + lpcs->cx;
if ((lp->wStyle & 0xf) != CBS_DROPDOWNLIST)
lp->ListBoxRect.right -= 5;
lp->ListBoxRect.bottom = lp->ListBoxRect.top + lpcs->cy -
wEditHeight + 1;
#endif
lp->ListBoxControl = CreateWindowEx(dwExStyle,"LISTBOX",/*"COMBOLBOX",*/
NULL, dwStyle,
lp->ListBoxRect.left, lp->ListBoxRect.top,
lp->ListBoxRect.right - lp->ListBoxRect.left,
lp->ListBoxRect.bottom - lp->ListBoxRect.top,
hWnd, 0,
hInst,(LPVOID)NULL);
#if MWCLIENT
#if 0
GrLowerWindow(lp->ListBoxControl->wid);
#endif
MwLowerWindow(lp->ListBoxControl);
#endif
#ifdef LATER
/* Microsoft Word 6.0 wants to see COMBOLBOX on top */
/* of Z-order... */
if (dwStyle & WS_POPUP)
{
SetWindowPos(lp->ListBoxControl, HWND_TOP,
0, 0, 0, 0,
SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
}
#endif
#if 0 /* jmt: fix: no HWND32(LPWININFO) */
/* physically expand client window,
if there is a scroll style
*/
if (lpcs->style & WS_VSCROLL)
{
HWND32 hWnd32 = GETHWND32(hWnd);
SetRectEmpty(&hWnd32->rcNC);
hWnd32->wWidth = (WORD) hWnd32->rWnd.right-hWnd32->rWnd.left;
hWnd32->wHeight = (WORD)hWnd32->rWnd.bottom-hWnd32->rWnd.top;
RELEASEWININFO(hWnd32);
}
#endif
/*
** Finally turn off border drawing and WM_?SCROLL styles to prevent creation
** of system scrollbars.
*/
dwStyle = GetWindowLong(hWnd, GWL_STYLE);
dwStyle &= ~(WS_VSCROLL | WS_HSCROLL | WS_BORDER | WS_DLGFRAME | WS_THICKFRAME);
SetWindowLong(hWnd, GWL_STYLE, dwStyle);
lp->nListItems = 0;
return TRUE;
case WM_DESTROY: /*WM_NCDESTROY:*/
if (IsWindow(lp->ListBoxControl))
DestroyWindow(lp->ListBoxControl);
if (IsWindow(lp->EditControl))
DestroyWindow(lp->EditControl);
WinFree((LPSTR)lp);
return 0L;
case WM_GETDLGCODE:
return (LRESULT)(DLGC_WANTCHARS|DLGC_WANTARROWS);
/* jmt: twine->mwin bug fixed: */
case WM_NCLBUTTONDOWN: /* jmt: a must */
#if 0 /* twine->mw buggy */
case WM_LBUTTONDOWN:
#endif
if ((lp->wStyle & 0xf) == CBS_SIMPLE)
break;
cp.x = (int)(short)LOWORD(lParam);
cp.y = (int)(short)HIWORD(lParam);
#if 1 /* WM_NCLBUTTONDOWM: */
ScreenToClient(hWnd, &cp); /* jmt: a must */
#endif
if (!IS_SET(lp, CSF_CAPTUREACTIVE)) /* no listbox yet */
{
/* click on a button or anywhere if it's dropdown combo */
if (PtInRect(&lp->ButtonRect, cp) ||
(lp->wStyle & 0x0F) == CBS_DROPDOWNLIST)
{
if (PtInRect(&lp->ButtonRect, cp))
CBoxDrawButton(hWnd, 1, lp);
cp.x = ((lp->wStyle & 0xf) != CBS_DROPDOWNLIST) ? 5 : 0;
cp.y = lp->uHeight - 1;
ClientToScreen(hWnd, &cp);
fprintf(stderr," (1)lp->ListBoxRect:(%d,%d,%d,%d)\n",
lp->ListBoxRect.left,
lp->ListBoxRect.top,
lp->ListBoxRect.right,
lp->ListBoxRect.bottom);
OffsetRect(&lp->ListBoxRect, cp.x - lp->ListBoxRect.left, cp.y - lp->ListBoxRect.top);
fprintf(stderr," (2)lp->ListBoxRect:(%d,%d,%d,%d)\n",
lp->ListBoxRect.left,
lp->ListBoxRect.top,
lp->ListBoxRect.right,
lp->ListBoxRect.bottom);
SetWindowPos(lp->ListBoxControl, HWND_TOP, /*0,*/
cp.x, cp.y, 0, 0,
SWP_NOSIZE | /*SWP_NOZORDER |*/ SWP_NOACTIVATE);
SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,CBN_DROPDOWN));
/* ECW added following conditional... 4/4/96 */
/* JMT following conditional is a must for microwindows 8/14/2k */
if (1) /* -(!IS_SET(lp, CSF_HASDROPPED)) jmt: a must */
{
/* ??first time it drops down, size it to hold all items?? */
int nitems = SendMessage(lp->ListBoxControl,LB_GETCOUNT,0,0L);
#if 0
/* resize if too small, in this case, also do too long */
if (lp->ListBoxRect.bottom - lp->ListBoxRect.top <
((lp->uHeight-2) * nitems))
{
#endif
nitems = (nitems > 12 ? 12 : nitems); /* a dozen, max */
#if 0 /* twine->mw buggy? */
lp->ListBoxRect.bottom =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -