📄 combobox.c
字号:
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 *)WinMalloc(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 =
lp->ListBoxRect.top + ((lp->uHeight-2) * nitems);
#endif
fprintf(stderr," (2.5)lp->ListBoxRect:(%d,%d,%d,%d)\n",
lp->ListBoxRect.left,
lp->ListBoxRect.top,
lp->ListBoxRect.right,
lp->ListBoxRect.bottom);
/* jmt: twine->mwin bug fixed: */
fprintf(stderr," 706: fixed: SetWindowPos(lp->ListBoxControl,,%d,%d,...)\n",cp.x,cp.y);
#if 0 /* twine->mwin bug */
SetWindowPos(lp->ListBoxControl,HWND_TOP,0,0,
lp->ListBoxRect.right - lp->ListBoxRect.left,
lp->ListBoxRect.bottom - lp->ListBoxRect.top,
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
#else /* jmt: twine->mwin bug fixed: */
SetWindowPos(lp->ListBoxControl,HWND_TOP,cp.x,cp.y,
lp->ListBoxRect.right - lp->ListBoxRect.left,
lp->ListBoxRect.bottom - lp->ListBoxRect.top,
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
#endif
#if 0
}
#endif
SET_STATE(lp, CSF_HASDROPPED);
}
/* End of addition */
ShowWindow(lp->ListBoxControl, SW_SHOW);
#if 0 /* orig(twine) */
SetFocus(lp->ListBoxControl);
#else /* jmt: mwclient */
SetForegroundWindow(lp->ListBoxControl);
#endif
CBoxCapture(hWnd, 1);
SET_STATE(lp, CSF_CAPTUREACTIVE);
SET_STATE(lp, CSF_BUTTONDOWN);
}
}
else
{ /* there is a listbox visible */
HWND hwndNewFocus = 0;
cpScreen = cp;
if ((lp->wStyle & 0xf) != CBS_SIMPLE)
{
ClientToScreen(hWnd, &cpScreen);
hwndNewFocus = WindowFromPoint(cpScreen);
}
fprintf(stderr," (3)lp->ListBoxRect:(%d,%d,%d,%d)\n",
lp->ListBoxRect.left,
lp->ListBoxRect.top,
lp->ListBoxRect.right,
lp->ListBoxRect.bottom);
if (PtInRect(&lp->ListBoxRect, cpScreen))
{
CBoxSendMouseToLBox(lp, WM_LBUTTONDOWN, wParam, cpScreen);
}
else
{
if (PtInRect(&lp->ButtonRect, cp))
CBoxDrawButton(hWnd, 0, lp);
if ((lp->wStyle & 0x0F) == CBS_DROPDOWN && hwndNewFocus == lp->EditControl)
/* don't close listbox */;
else {
SendMessage(lp->hWndParent, WM_COMMAND, GET_WM_COMMAND_MPS(lp->nID,hWnd,CBN_CLOSEUP));
fprintf(stderr," 802: (hide) SetWindowPos(lp->ListBoxControl, , 0, 0, 0, 0,..)\n");
SetWindowPos(lp->ListBoxControl, 0,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_HIDEWINDOW);
#if MWCLIENT
MwLowerWindow(lp->ListBoxControl);
#endif
CBoxCapture(hWnd, 0);
CLEAR_STATE(lp, CSF_BUTTONDOWN);
}
CLEAR_STATE(lp, CSF_CAPTUREACTIVE);
if (hwndNewFocus && hwndNewFocus != hWnd)
{
ScreenToClient(hwndNewFocus, &cpScreen);
SetFocus(hwndNewFocus);
SendMessage(hwndNewFocus, WM_LBUTTONDOWN, wParam, MAKELONG(cpScreen.x, cpScreen.y));
}
} /* !(PtInRect(&lp->ListBoxRect, cpScreen)) */
}
break;
/* jmt: twine->mwin bug fixed: */
case WM_NCMOUSEMOVE:
#if 0 /* jmt: twine->mw buggy */
case WM_MOUSEMOVE:
#endif
if (!IS_SET(lp,CSF_BUTTONDOWN) && ((lp->wStyle & 0xf) == CBS_SIMPLE))
break;
cp.x = (int)(short)LOWORD(lParam);
cp.y = (int)(short)HIWORD(lParam);
#if 1 /* WM_NCMOUSEMOVE: */
ScreenToClient(hWnd, &cp); /* jmt: a must */
#endif
if (IS_SET(lp, CSF_CAPTUREACTIVE))
{
if (PtInRect(&lp->ButtonRect,cp))
{
if (!IS_SET(lp, CSF_LOCALBUTTONDOWN))
CBoxDrawButton(hWnd, 1, lp);
break;
}
if ((lp->wStyle & 0xf) != CBS_SIMPLE)
ClientToScreen(hWnd,&cp);
if (PtInRect(&lp->ListBoxRect,cp))
{
CBoxSendMouseToLBox(lp,WM_MOUSEMOVE,wParam,cp);
}
if (IS_SET(lp,CSF_LOCALBUTTONDOWN) && ((lp->wStyle & 0xf) != CBS_SIMPLE))
CBoxDrawButton(hWnd,0,lp);
}
break;
/* jmt: twine->mwin bug fixed: */
case WM_NCLBUTTONUP:
#if 0 /* twine->mw buggy */
case WM_LBUTTONUP:
#endif
if (!IS_SET(lp, CSF_CAPTUREACTIVE))
break;
cp.x = (int)(short)LOWORD(lParam);
cp.y = (int)(short)HIWORD(lParam);
#if 1 /* WM_NCLBUTTONUP */
ScreenToClient(hWnd, &cp); /* jmt: a must */
#endif
CLEAR_STATE(lp,CSF_BUTTONDOWN);
if (PtInRect(&lp->ButtonRect, cp))
/*(lp->wStyle & 0x0F) == CBS_DROPDOWNLIST)*/
{
if (PtInRect(&lp->ButtonRect, cp))
CBoxDrawButton(hWnd, 0, lp);
if (IS_SET(lp, CSF_LBOXBUTTONDOWN))
{
if ((lp->wStyle & 0xf) != CBS_SIMPLE)
ClientToScreen(hWnd, &cp);
CBoxSendMouseToLBox(lp, WM_LBUTTONUP, wParam, cp);
CLEAR_STATE(lp,CSF_LBOXBUTTONDOWN);
}
break;
}
if ((lp->wStyle & 0xf) != CBS_SIMPLE)
ClientToScreen(hWnd, &cp);
if (PtInRect(&lp->ListBoxRect, cp))
{
uiKey = (UINT)SendMessage(lp->ListBoxControl, LB_GETCURSEL, 0, 0);
if (uiKey != (UINT)LB_ERR)
{
if (lp->EditControl)
{
SetFocus(lp->EditControl);
CBoxDrawEdit(lp, hWnd, uiKey);
}
else {
SetFocus(hWnd);
CBoxDrawStatic(lp, hWnd, uiKey);
}
/* LATER check the WS_EX_NOPARENTNOTIFY bit in ext style.*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -