📄 comboex.c
字号:
x = xioff + CBE_STARTOFFSET + 1;
w = rect.right-rect.left - x - GetSystemMetrics(SM_CXVSCROLL) - 1;
h = mysize.cy + 1;
y = rect.bottom - h - 1;
TRACE("Combo client (%d,%d)-(%d,%d), setting Edit to (%d,%d)-(%d,%d)\n",
rect.left, rect.top, rect.right, rect.bottom, x, y, x + w, y + h);
SetWindowPos(infoPtr->hwndEdit, HWND_TOP, x, y, w, h,
SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
}
static void COMBOEX_ReSize (COMBOEX_INFO *infoPtr)
{
SIZE mysize;
LONG cy;
IMAGEINFO iinfo;
COMBOEX_GetComboFontSize (infoPtr, &mysize);
cy = mysize.cy + CBE_EXTRA;
if (infoPtr->himl && ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo)) {
cy = max (iinfo.rcImage.bottom - iinfo.rcImage.top, cy);
TRACE("upgraded height due to image: height=%d\n", cy);
}
SendMessageW (infoPtr->hwndSelf, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)cy);
if (infoPtr->hwndCombo) {
SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT,
(WPARAM) 0, (LPARAM) cy);
if ( !(infoPtr->flags & CBES_EX_NOSIZELIMIT)) {
RECT comboRect;
if (GetWindowRect(infoPtr->hwndCombo, &comboRect)) {
RECT ourRect;
if (GetWindowRect(infoPtr->hwndSelf, &ourRect)) {
if (comboRect.bottom > ourRect.bottom) {
POINT pt = { ourRect.left, ourRect.top };
if (ScreenToClient(infoPtr->hwndSelf, &pt))
MoveWindow( infoPtr->hwndSelf, pt.x, pt.y, ourRect.right - ourRect.left,
comboRect.bottom - comboRect.top, FALSE);
}
}
}
}
}
}
static void COMBOEX_SetEditText (COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item)
{
if (!infoPtr->hwndEdit) return;
/* native issues the following messages to the {Edit} control */
/* WM_SETTEXT (0,addr) */
/* EM_SETSEL32 (0,0) */
/* EM_SETSEL32 (0,-1) */
if (item->mask & CBEIF_TEXT) {
SendMessageW (infoPtr->hwndEdit, WM_SETTEXT, 0, (LPARAM)COMBOEX_GetText(infoPtr, item));
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
}
}
static CBE_ITEMDATA * COMBOEX_FindItem(COMBOEX_INFO *infoPtr, INT index)
{
CBE_ITEMDATA *item;
INT i;
if ((index >= infoPtr->nb_items) || (index < -1))
return 0;
if (index == -1)
return infoPtr->edit;
item = infoPtr->items;
i = infoPtr->nb_items - 1;
/* find the item in the list */
while (item && (i > index)) {
item = item->next;
i--;
}
if (!item || (i != index)) {
ERR("COMBOBOXEX item structures broken. Please report!\n");
return 0;
}
return item;
}
static inline BOOL COMBOEX_HasEdit(COMBOEX_INFO *infoPtr)
{
return infoPtr->hwndEdit ? TRUE : FALSE;
}
/* *** CBEM_xxx message support *** */
static UINT COMBOEX_GetListboxText(COMBOEX_INFO *infoPtr, int n, LPWSTR buf)
{
CBE_ITEMDATA *item;
LPCWSTR str;
item = COMBOEX_FindItem(infoPtr, n);
if (!item)
return 0;
str = COMBOEX_GetText(infoPtr, item);
if (infoPtr->unicode)
{
if (buf)
lstrcpyW(buf, str);
return lstrlenW(str);
}
else
{
UINT r;
r = WideCharToMultiByte(CP_ACP, 0, str, -1, (LPSTR)buf, 0x40000000, NULL, NULL);
if (r) r--;
return r;
}
}
static INT COMBOEX_DeleteItem (COMBOEX_INFO *infoPtr, INT index)
{
CBE_ITEMDATA *item;
TRACE("(index=%d)\n", index);
/* if item number requested does not exist then return failure */
if ((index >= infoPtr->nb_items) || (index < 0)) return CB_ERR;
if (!(item = COMBOEX_FindItem(infoPtr, index))) return CB_ERR;
/* doing this will result in WM_DELETEITEM being issued */
SendMessageW (infoPtr->hwndCombo, CB_DELETESTRING, (WPARAM)index, 0);
return infoPtr->nb_items;
}
static BOOL COMBOEX_GetItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
{
INT index = cit->iItem;
CBE_ITEMDATA *item;
TRACE("(...)\n");
/* if item number requested does not exist then return failure */
if ((index >= infoPtr->nb_items) || (index < -1)) return FALSE;
/* if the item is the edit control and there is no edit control, skip */
if ((index == -1) && !COMBOEX_HasEdit(infoPtr)) return FALSE;
if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE;
COMBOEX_CopyItem (item, cit);
return TRUE;
}
static BOOL COMBOEX_GetItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
{
COMBOBOXEXITEMW tmpcit;
TRACE("(...)\n");
tmpcit.mask = cit->mask;
tmpcit.iItem = cit->iItem;
tmpcit.pszText = 0;
if(!COMBOEX_GetItemW (infoPtr, &tmpcit)) return FALSE;
if (is_textW(tmpcit.pszText) && cit->pszText)
WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1,
cit->pszText, cit->cchTextMax, NULL, NULL);
else if (cit->pszText) cit->pszText[0] = 0;
else cit->pszText = (LPSTR)tmpcit.pszText;
cit->iImage = tmpcit.iImage;
cit->iSelectedImage = tmpcit.iSelectedImage;
cit->iOverlay = tmpcit.iOverlay;
cit->iIndent = tmpcit.iIndent;
cit->lParam = tmpcit.lParam;
return TRUE;
}
inline static BOOL COMBOEX_HasEditChanged (COMBOEX_INFO *infoPtr)
{
return COMBOEX_HasEdit(infoPtr) &&
(infoPtr->flags & WCBE_EDITHASCHANGED) == WCBE_EDITHASCHANGED;
}
static INT COMBOEX_InsertItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
{
INT index;
CBE_ITEMDATA *item;
NMCOMBOBOXEXW nmcit;
TRACE("\n");
if (TRACE_ON(comboex)) COMBOEX_DumpInput (cit);
/* get real index of item to insert */
index = cit->iItem;
if (index == -1) index = infoPtr->nb_items;
if (index > infoPtr->nb_items) return -1;
/* get zero-filled space and chain it in */
if(!(item = (CBE_ITEMDATA *)Alloc (sizeof(*item)))) return -1;
/* locate position to insert new item in */
if (index == infoPtr->nb_items) {
/* fast path for iItem = -1 */
item->next = infoPtr->items;
infoPtr->items = item;
}
else {
INT i = infoPtr->nb_items-1;
CBE_ITEMDATA *moving = infoPtr->items;
while ((i > index) && moving) {
moving = moving->next;
i--;
}
if (!moving) {
ERR("COMBOBOXEX item structures broken. Please report!\n");
Free(item);
return -1;
}
item->next = moving->next;
moving->next = item;
}
/* fill in our hidden item structure */
item->mask = cit->mask;
if (item->mask & CBEIF_TEXT) {
INT len = 0;
if (is_textW(cit->pszText)) len = strlenW (cit->pszText);
if (len > 0) {
item->pszText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
if (!item->pszText) {
Free(item);
return -1;
}
strcpyW (item->pszText, cit->pszText);
}
else if (cit->pszText == LPSTR_TEXTCALLBACKW)
item->pszText = LPSTR_TEXTCALLBACKW;
item->cchTextMax = cit->cchTextMax;
}
if (item->mask & CBEIF_IMAGE)
item->iImage = cit->iImage;
if (item->mask & CBEIF_SELECTEDIMAGE)
item->iSelectedImage = cit->iSelectedImage;
if (item->mask & CBEIF_OVERLAY)
item->iOverlay = cit->iOverlay;
if (item->mask & CBEIF_INDENT)
item->iIndent = cit->iIndent;
if (item->mask & CBEIF_LPARAM)
item->lParam = cit->lParam;
infoPtr->nb_items++;
if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);
SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING,
(WPARAM)cit->iItem, (LPARAM)item);
memset (&nmcit.ceItem, 0, sizeof(nmcit.ceItem));
COMBOEX_CopyItem (item, &nmcit.ceItem);
COMBOEX_NotifyItem (infoPtr, CBEN_INSERTITEM, &nmcit);
return index;
}
static INT COMBOEX_InsertItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
{
COMBOBOXEXITEMW citW;
LPWSTR wstr = NULL;
INT ret;
memcpy(&citW,cit,sizeof(COMBOBOXEXITEMA));
if (cit->mask & CBEIF_TEXT && is_textA(cit->pszText)) {
INT len = MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, NULL, 0);
wstr = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
if (!wstr) return -1;
MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, wstr, len);
citW.pszText = wstr;
}
ret = COMBOEX_InsertItemW(infoPtr, &citW);
if (wstr) Free(wstr);
return ret;
}
static DWORD
COMBOEX_SetExtendedStyle (COMBOEX_INFO *infoPtr, DWORD mask, DWORD style)
{
DWORD dwTemp;
TRACE("(mask=x%08x, style=0x%08x)\n", mask, style);
dwTemp = infoPtr->dwExtStyle;
if (mask)
infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~mask) | style;
else
infoPtr->dwExtStyle = style;
/* see if we need to change the word break proc on the edit */
if ((infoPtr->dwExtStyle ^ dwTemp) & CBES_EX_PATHWORDBREAKPROC)
SetPathWordBreakProc(infoPtr->hwndEdit,
(infoPtr->dwExtStyle & CBES_EX_PATHWORDBREAKPROC) ? TRUE : FALSE);
/* test if the control's appearance has changed */
mask = CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT;
if ((infoPtr->dwExtStyle & mask) != (dwTemp & mask)) {
/* if state of EX_NOEDITIMAGE changes, invalidate all */
TRACE("EX_NOEDITIMAGE state changed to %d\n",
infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE);
InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
COMBOEX_AdjustEditPos (infoPtr);
if (infoPtr->hwndEdit)
InvalidateRect (infoPtr->hwndEdit, NULL, TRUE);
}
return dwTemp;
}
static HIMAGELIST COMBOEX_SetImageList (COMBOEX_INFO *infoPtr, HIMAGELIST himl)
{
HIMAGELIST himlTemp = infoPtr->himl;
TRACE("(...)\n");
infoPtr->himl = himl;
COMBOEX_ReSize (infoPtr);
InvalidateRect (infoPtr->hwndCombo, NULL, TRUE);
/* reposition the Edit control based on whether icon exists */
COMBOEX_AdjustEditPos (infoPtr);
return himlTemp;
}
static BOOL COMBOEX_SetItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
{
INT index = cit->iItem;
CBE_ITEMDATA *item;
if (TRACE_ON(comboex)) COMBOEX_DumpInput (cit);
/* if item number requested does not exist then return failure */
if ((index >= infoPtr->nb_items) || (index < -1)) return FALSE;
/* if the item is the edit control and there is no edit control, skip */
if ((index == -1) && !COMBOEX_HasEdit(infoPtr)) return FALSE;
if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE;
/* add/change stuff to the internal item structure */
item->mask |= cit->mask;
if (cit->mask & CBEIF_TEXT) {
INT len = 0;
COMBOEX_FreeText(item);
if (is_textW(cit->pszText)) len = strlenW(cit->pszText);
if (len > 0) {
item->pszText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
if (!item->pszText) return FALSE;
strcpyW(item->pszText, cit->pszText);
} else if (cit->pszText == LPSTR_TEXTCALLBACKW)
item->pszText = LPSTR_TEXTCALLBACKW;
item->cchTextMax = cit->cchTextMax;
}
if (cit->mask & CBEIF_IMAGE)
item->iImage = cit->iImage;
if (cit->mask & CBEIF_SELECTEDIMAGE)
item->iSelectedImage = cit->iSelectedImage;
if (cit->mask & CBEIF_OVERLAY)
item->iOverlay = cit->iOverlay;
if (cit->mask & CBEIF_INDENT)
item->iIndent = cit->iIndent;
if (cit->mask & CBEIF_LPARAM)
cit->lParam = cit->lParam;
if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);
/* if original request was to update edit control, do some fast foot work */
if (cit->iItem == -1) {
COMBOEX_SetEditText (infoPtr, item);
RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | RDW_INVALIDATE);
}
return TRUE;
}
static BOOL COMBOEX_SetItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
{
COMBOBOXEXITEMW citW;
LPWSTR wstr = NULL;
BOOL ret;
memcpy(&citW, cit, sizeof(COMBOBOXEXITEMA));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -