INT LBPage( PLBIV plb, INT startItem, BOOL fPageForwardDirection) { INT i; INT height; RECT rc; if (plb->cMac == 1) return(0); _GetClientRect(plb->spwnd, &rc); height = rc.bottom; i = startItem; if (fPageForwardDirection) { while ((height >= 0) && (i < plb->cMac)) height -= LBGetVariableHeightItemHeight(plb, i++); return((height >= 0) ? plb->cMac - 1 : max(i - 2, startItem + 1)); } else { while ((height >= 0) && (i >= 0)) height -= LBGetVariableHeightItemHeight(plb, i--); return((height >= 0) ? 0 : min(i + 2, startItem - 1)); } }
void CCandidateWindow::_OnLButtonDown(POINT pt) { RECT rcWindow = {0, 0, 0, 0};; _GetClientRect(&rcWindow); int cyLine = _cyRow; UINT index = 0; int currentPage = _CandidateIndexToPageNumber(_currentSelection); // Hit test on list items index = _PageNumberToCandidateIndex(currentPage); for (UINT pageCount = 0; (index < _candidateList.size()) && (pageCount < _numCandidatesPerPage); index++, pageCount++) { RECT rc = {0, 0, 0, 0}; rc.left = rcWindow.left; rc.right = rcWindow.right - GetSystemMetrics(SM_CXVSCROLL) * 2; rc.top = rcWindow.top + (pageCount * cyLine); rc.bottom = rcWindow.top + ((pageCount + 1) * cyLine); if (PtInRect(&rc, pt) && _pfnCallback) { SetCursor(LoadCursor(NULL, IDC_HAND)); _currentSelection = index; _pfnCallback(_pObj, CAND_ITEM_SELECT); return; } } SetCursor(LoadCursor(NULL, IDC_ARROW)); }
void CCandidateWindow::_OnMouseMove(POINT pt) { RECT rcWindow = {0, 0, 0, 0}; _GetClientRect(&rcWindow); RECT rc = {0, 0, 0, 0}; rc.left = rcWindow.left; rc.right = rcWindow.right - GetSystemMetrics(SM_CXVSCROLL) * 2; rc.top = rcWindow.top; rc.bottom = rcWindow.bottom; if (PtInRect(&rc, pt)) { SetCursor(LoadCursor(NULL, IDC_HAND)); return; } SetCursor(LoadCursor(NULL, IDC_ARROW)); if (_pVScrollBarWnd) { _pVScrollBarWnd->_GetClientRect(&rc); MapWindowPoints(_GetWnd(), _pVScrollBarWnd->_GetWnd(), &pt, 1); if (PtInRect(&rc, pt)) { _pVScrollBarWnd->_OnMouseMove(pt); } } }
void CScrollButtonWindow::_OnTimer() { POINT pt = {0, 0}; CScrollBarWindow* pParent = (CScrollBarWindow*)_GetParent(); // more secure w/ dynamic_cast if (pParent == nullptr) { return; } // start another faster timer _StartTimer(_GetScrollSpeed()); GetCursorPos(&pt); MapWindowPoints(HWND_DESKTOP, pParent->_GetWnd(), &pt, 1); RECT rc = {0, 0, 0, 0}; _GetClientRect(&rc); if (PtInRect(&rc, pt)) { switch (subTypeOfControl) { case DFCS_SCROLLDOWN: _NotifyCommand(WM_VSCROLL, SB_LINEDOWN, 0); pParent->_ShiftLine(+1, FALSE); break; case DFCS_SCROLLUP: _NotifyCommand(WM_VSCROLL, SB_LINEUP, 0); pParent->_ShiftLine(-1, FALSE); break; } } }
void CScrollButtonWindow::_OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps) { pps; RECT rc = {0, 0, 0, 0}; _GetClientRect(&rc); DrawFrameControl(dcHandle, &rc, DFC_SCROLL, subTypeOfControl | typeOfControl | (!_IsEnabled() ? DFCS_INACTIVE : 0)); }
void GetRealClientRect( PWND pwnd, LPRECT prc, UINT uFlags) { if (GETFNID(pwnd) == FNID_DESKTOP) { *prc = (uFlags & GRC_FULLSCREEN) ? pwnd->rcWindow : gpsi->rcWork; } else { _GetClientRect(pwnd, prc); if (uFlags & GRC_SCROLLS) { if (TestWF(pwnd, WFHPRESENT)) prc->bottom += SYSMET(CYHSCROLL); if (TestWF(pwnd, WFVPRESENT)) prc->right += SYSMET(CXVSCROLL); } } if (uFlags & GRC_MINWNDS) { switch (SYSMET(ARRANGE) & ~ARW_HIDE) { case ARW_TOPLEFT | ARW_RIGHT: case ARW_TOPRIGHT | ARW_LEFT: // // Leave space on top for one row of min windows // prc->top += SYSMET(CYMINSPACING); break; case ARW_TOPLEFT | ARW_DOWN: case ARW_BOTTOMLEFT | ARW_UP: // // Leave space on left for one column of min windows // prc->left += SYSMET(CXMINSPACING); break; case ARW_TOPRIGHT | ARW_DOWN: case ARW_BOTTOMRIGHT | ARW_UP: // // Leave space on right for one column of min windows // prc->right -= SYSMET(CXMINSPACING); break; case ARW_BOTTOMLEFT | ARW_RIGHT: case ARW_BOTTOMRIGHT | ARW_LEFT: // // Leave space on bottom for one row of min windows // prc->bottom -= SYSMET(CYMINSPACING); break; } } }
//----获得窗口客户矩形区--------------------------------------------------------- //描述: 获得窗口客户矩形区,矩形为客户坐标. //参数:hwnd:窗口句柄 // prc:用于保存矩形数据的指针. //返回:TRUE:成功; FALSE:失败 //------------------------------------------------------------------------------ BOOL GetClientRect(HWND hwnd,RECT *prc) { if(NULL!=prc) if(HWND_Lock(hwnd)) { _GetClientRect(hwnd,prc); HWND_Unlock(hwnd); return TRUE; } return FALSE; }
void CCandidateWindow::_OnLButtonDown(POINT pt) { RECT rcWindow = {0, 0, 0, 0};; _GetClientRect(&rcWindow); int cyLine = _cyRow; UINT candidateListPageCnt = _pIndexRange->Count(); UINT index = 0; int currentPage = 0; if (FAILED(_GetCurrentPage(¤tPage))) { return; } // Hit test on list items index = *_PageIndex.GetAt(currentPage); for (UINT pageCount = 0; (index < _candidateList.Count()) && (pageCount < candidateListPageCnt); index++, pageCount++) { RECT rc = {0, 0, 0, 0}; rc.left = rcWindow.left; rc.right = rcWindow.right - GetSystemMetrics(SM_CXVSCROLL) * 2; rc.top = rcWindow.top + (pageCount * cyLine); rc.bottom = rcWindow.top + ((pageCount + 1) * cyLine); if (PtInRect(&rc, pt) && _pfnCallback) { SetCursor(LoadCursor(NULL, IDC_HAND)); _currentSelection = index; _pfnCallback(_pObj, CAND_ITEM_SELECT); return; } } SetCursor(LoadCursor(NULL, IDC_ARROW)); if (_pVScrollBarWnd) { RECT rc = {0, 0, 0, 0}; _pVScrollBarWnd->_GetClientRect(&rc); MapWindowPoints(_GetWnd(), _pVScrollBarWnd->_GetWnd(), &pt, 1); if (PtInRect(&rc, pt)) { _pVScrollBarWnd->_OnLButtonDown(pt); } } }
void CCandidateWindow::_ResizeWindow() { SIZE size = {0, 0}; _cxTitle = max(_cxTitle, size.cx + 2 * GetSystemMetrics(SM_CXFRAME)); CBaseWindow::_Resize(0, 0, _cxTitle, _cyRow * this->_numCandidatesPerPage + _cyHelpText ); RECT rcCandRect = {0, 0, 0, 0}; _GetClientRect(&rcCandRect); int letf = rcCandRect.right - GetSystemMetrics(SM_CXVSCROLL) * 2 - CANDWND_BORDER_WIDTH; int top = rcCandRect.top + CANDWND_BORDER_WIDTH; int width = GetSystemMetrics(SM_CXVSCROLL) * 2; int height = rcCandRect.bottom - rcCandRect.top - CANDWND_BORDER_WIDTH * 2; }
INT CItemInWindowVarOwnerDraw( PLBIV plb, BOOL fPartial) { RECT rect; INT sItem; INT clientbottom; _GetClientRect(plb->spwnd, (LPRECT)&rect); clientbottom = rect.bottom; /* * Find the number of var height ownerdraw items which are visible starting * from plb->iTop. */ for (sItem = plb->iTop; sItem < plb->cMac; sItem++) { /* * Find out if the item is visible or not */ if (!LBGetItemRect(plb, sItem, (LPRECT)&rect)) { /* * This is the first item which is completely invisible, so return * how many items are visible. */ return (sItem - plb->iTop); } if (!fPartial && rect.bottom > clientbottom) { /* * If we only want fully visible items, then if this item is * visible, we check if the bottom of the item is below the client * rect, so we return how many are fully visible. */ return (sItem - plb->iTop - 1); } } /* * All the items are visible */ return (plb->cMac - plb->iTop); }
BOOL CScrollBarWindow::_GetBtnDnRect(_Out_ RECT *prc) { RECT rc = {0, 0, 0, 0}; _GetClientRect(&rc); if (prc == nullptr) { return FALSE; } prc->left = rc.left; prc->top = rc.bottom - min(_sizeOfScrollBtn.cy, (rc.bottom - rc.top)/2); prc->right = rc.right; prc->bottom = rc.bottom; return TRUE; }
void CCandidateWindow::_ResizeWindow() { SIZE size = {0, 0}; _cxTitle = max(_cxTitle, size.cx + 2 * GetSystemMetrics(SM_CXFRAME)); int candidateListPageCnt = _pIndexRange->Count(); CBaseWindow::_Resize(0, 0, _cxTitle, _cyRow * candidateListPageCnt); RECT rcCandRect = {0, 0, 0, 0}; _GetClientRect(&rcCandRect); int letf = rcCandRect.right - GetSystemMetrics(SM_CXVSCROLL) * 2 - CANDWND_BORDER_WIDTH; int top = rcCandRect.top + CANDWND_BORDER_WIDTH; int width = GetSystemMetrics(SM_CXVSCROLL) * 2; int height = rcCandRect.bottom - rcCandRect.top - CANDWND_BORDER_WIDTH * 2; _pVScrollBarWnd->_Resize(letf, top, width, height); }
void CCandidateWindow::_OnMouseMove(POINT pt) { RECT rcWindow = {0, 0, 0, 0}; _GetClientRect(&rcWindow); RECT rc = {0, 0, 0, 0}; rc.left = rcWindow.left; rc.right = rcWindow.right - GetSystemMetrics(SM_CXVSCROLL) * 2; rc.top = rcWindow.top; rc.bottom = rcWindow.bottom; if (PtInRect(&rc, pt)) { SetCursor(LoadCursor(NULL, IDC_HAND)); return; } SetCursor(LoadCursor(NULL, IDC_ARROW)); }
void CScrollBarWindow::_GetScrollArea(_Out_ RECT *prc) { RECT rcBtnUp = {0, 0, 0, 0}; RECT rcBtnDn = {0, 0, 0, 0}; _GetBtnUpRect(&rcBtnUp); _GetBtnDnRect(&rcBtnDn); RECT rc = {0, 0, 0, 0}; _GetClientRect(&rc); if (prc == nullptr) { return; } prc->left = rc.left; prc->top = rc.top + (rcBtnUp.bottom - rcBtnUp.top); prc->right = rc.right; prc->bottom = rc.bottom - (rcBtnDn.bottom - rcBtnDn.top); }
INT LBCalcVarITopScrollAmt( PLBIV plb, INT iTopOld, INT iTopNew) { RECT rc; RECT rcClient; _GetClientRect(plb->spwnd, (LPRECT)&rcClient); /* * Just optimize redrawing when move +/- 1 item. We will redraw all items * if moving more than 1 item ahead or back. This is good enough for now. */ if (iTopOld + 1 == iTopNew) { /* * We are scrolling the current iTop up off the top off the listbox so * return a negative number. */ LBGetItemRect(plb, iTopOld, (LPRECT)&rc); return (rcClient.top - rc.bottom); } if (iTopOld - 1 == iTopNew) { /* * We are scrolling the current iTop down and the previous item is * becomming the new iTop so return a positive number. */ LBGetItemRect(plb, iTopNew, (LPRECT)&rc); return -rc.top; } return rcClient.bottom - rcClient.top; }
void duTreeCtrl::DrawObject(HDC hDC) { duRect rcTreeCtrl; Plugin_GetRect(this, &rcTreeCtrl); rcTreeCtrl.OffsetRect(-rcTreeCtrl.left, -rcTreeCtrl.top); BITMAPINFO bmInfo; BYTE *pBits; HDC hMemDC = ::CreateCompatibleDC(hDC); InitBitmapInfo(&bmInfo, rcTreeCtrl.Width(), rcTreeCtrl.Height()); HBITMAP hBmp = ::CreateDIBSection(hDC, &bmInfo, DIB_RGB_COLORS,(void**)&pBits, 0, 0); HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDC, hBmp); BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; ::AlphaBlend(hMemDC, 0, 0, rcTreeCtrl.Width(), rcTreeCtrl.Height(), hDC, 0, 0, rcTreeCtrl.Width(), rcTreeCtrl.Height(), bf); duStyleGroup *pStyleGroup = (duStyleGroup *)GetResObj(GetStyle(), DU_RES_STYLEGROUP); if (pStyleGroup) pStyleGroup->Draw(hMemDC, &rcTreeCtrl, GetState(), NULL, GetAlpha()); int nOffsetY = 0; TreeCtrlItem *pFirstVisible = GetFirstVisibleItem(nOffsetY); if (pFirstVisible == NULL || pFirstVisible == m_pRoot) return; duRect rcClient = _GetClientRect(); POINT ptView = GetViewPoint(); duFont *pFont = (duFont *)GetResObj(m_szFont, DU_RES_FONT); duSize sizeView; GetViewSize(&sizeView); int nDrawHeight = -nOffsetY; TreeCtrlItem *pItem = pFirstVisible; while (pItem) { duRect rcItem; rcItem.left = -ptView.x; rcItem.right = rcClient.right; rcItem.top = nDrawHeight; rcItem.bottom = rcItem.top + m_nItemHeight; UINT uItemState = DU_STATE_NORMAL; if (pItem == m_pHot) uItemState = DU_STATE_OVER; if (pItem == m_pSelect) uItemState = DU_STATE_PRESS; DrawByStyle(this, m_szItemStyle, hMemDC, &rcItem, uItemState, NULL, GetAlpha()); // draw indent[-+] int nLeft = (pItem->nLevel - 1) * m_nIndentWidth; duRect rcIndent = CalcVCenterRect(rcItem, nLeft, m_nIndentWidth, m_nIndentHeight); if (ItemHasChildren(pItem)) { UINT nIndentState = pItem->fExpand ? DU_STATE_NORMAL : DU_STATE_CHECKED; DrawByStyle(this, m_szIndentStyle, hMemDC, &rcIndent, nIndentState, NULL, GetAlpha()); } // draw icon nLeft += (m_nIndentWidth + m_nIndentIconSpace); duRect rcIcon = CalcVCenterRect(rcItem, nLeft, m_nIconWidth, m_nIconHeight); duImage *pIcon = (duImage *)GetResObj(pItem->strImage.c_str(), DU_RES_IMAGE); if (pIcon) DrawNormal(hMemDC, rcIcon.left, rcIcon.top, rcIcon.Width(), rcIcon.Height(), pIcon, 0, 0, GetAlpha()); // draw text duRect rcText; nLeft += (m_nIconWidth + m_nIconTextSpace); rcText = rcItem; rcText.left = rcItem.left + nLeft; if (pItem->strText.length() > 0) DrawText32Bpp(hMemDC, pFont, m_clrText, pItem->strText.c_str(), pItem->strText.length(), &rcText, DT_LEFT|DT_VCENTER|DT_SINGLELINE, GetAlpha()); if (nDrawHeight - nOffsetY > rcTreeCtrl.Height()) break; nDrawHeight += m_nItemHeight; pItem = GetNextVisibleItem(pItem); } ::AlphaBlend(hDC, 0, 0, rcTreeCtrl.Width(), rcTreeCtrl.Height(), hMemDC, 0, 0, rcTreeCtrl.Width(), rcTreeCtrl.Height(), bf); ::SelectObject(hMemDC, hOldBitmap); ::DeleteObject(hBmp); ::DeleteDC(hMemDC); }
LRESULT APIENTRY ListBoxWndProcWorker( PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, DWORD fAnsi) { HWND hwnd = HWq(pwnd); PAINTSTRUCT ps; HDC hdc; LPRECT lprc; PLBIV plb; /* List Box Instance Variable */ INT iSel; /* Index of selected item */ DWORD dw; TL tlpwndParent; UINT wFlags; LPWSTR lpwsz = NULL; LRESULT lReturn = 0; static BOOL fInit = TRUE; CheckLock(pwnd); VALIDATECLASSANDSIZE(pwnd, FNID_LISTBOX); INITCONTROLLOOKASIDE(&ListboxLookaside, LBIV, spwnd, 4); /* * Get the plb for the given window now since we will use it a lot in * various handlers. This was stored using SetWindowLong(hwnd,0,plb) * when the listbox was first created (by INITCONTROLLOOKASIDE above) */ plb = ((PLBWND)pwnd)->pLBIV; /* * Handle ANSI translations of input parameters */ if (fAnsi) { switch (message) { case LB_ADDSTRING: case LB_ADDSTRINGUPPER: case LB_ADDSTRINGLOWER: case LB_FINDSTRING: case LB_FINDSTRINGEXACT: case LB_INSERTSTRING: case LB_INSERTSTRINGUPPER: case LB_INSERTSTRINGLOWER: case LB_SELECTSTRING: if (!plb->fHasStrings) { break; } // Fall through... case LB_ADDFILE: case LB_DIR: if (lParam) { if (!MBToWCS((LPSTR)lParam, -1, &lpwsz, -1, TRUE)) return LB_ERR; } break; default: break; } if (lpwsz) { lParam = (LPARAM)lpwsz; } } switch (message) { case LB_GETTOPINDEX: // Return index of top item displayed. return plb->iTop; case LB_SETTOPINDEX: if (wParam && ((INT)wParam < 0 || (INT)wParam >= plb->cMac)) { RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); return LB_ERR; } if (plb->cMac) { xxxNewITop(plb, (INT)wParam); } break; case WM_STYLECHANGED: plb->fRtoLReading = (TestWF(pwnd, WEFRTLREADING) != 0); plb->fRightAlign = (TestWF(pwnd, WEFRIGHT) != 0); xxxCheckRedraw(plb, FALSE, 0); break; case WM_WINDOWPOSCHANGED: /* * If we are in the middle of creation, ignore this * message because it will generate a WM_SIZE message. * See xxxLBCreate(). */ if (!plb->fIgnoreSizeMsg) goto CallDWP; break; case WM_SIZE: /* * If we are in the middle of creation, ignore size * messages. See xxxLBCreate(). */ if (!plb->fIgnoreSizeMsg) xxxLBSize(plb, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_ERASEBKGND: ThreadLock(plb->spwndParent, &tlpwndParent); FillWindow(HW(plb->spwndParent), hwnd, (HDC)wParam, (HBRUSH)CTLCOLOR_LISTBOX); ThreadUnlock(&tlpwndParent); return TRUE; case LB_RESETCONTENT: xxxLBResetContent(plb); break; case WM_TIMER: if (wParam == IDSYS_LBSEARCH) { plb->iTypeSearch = 0; NtUserKillTimer(hwnd, IDSYS_LBSEARCH); xxxInvertLBItem(plb, plb->iSel, TRUE); break; } message = WM_MOUSEMOVE; xxxTrackMouse(plb, message, plb->ptPrev); break; /* * Fall through */ case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: { POINT pt; POINTSTOPOINT(pt, lParam); xxxTrackMouse(plb, message, pt); } break; case WM_MBUTTONDOWN: EnterReaderModeHelper(hwnd); break; case WM_CAPTURECHANGED: // // Note that this message should be handled only on unexpected // capture changes currently. // UserAssert(TestWF(pwnd, WFWIN40COMPAT)); if (plb->fCaptured) xxxLBButtonUp(plb, LBUP_NOTIFY); break; case LBCB_STARTTRACK: // // Start tracking mouse moves in the listbox, setting capture // if (!plb->pcbox) break; plb->fCaptured = FALSE; if (wParam) { POINT pt; POINTSTOPOINT(pt, lParam); _ScreenToClient(pwnd, &pt); xxxTrackMouse(plb, WM_LBUTTONDOWN, pt); } else { NtUserSetCapture(hwnd); plb->fCaptured = TRUE; plb->iLastSelection = plb->iSel; } break; case LBCB_ENDTRACK: // Kill capture, tracking, etc. if (plb->fCaptured) xxxLBButtonUp(plb, LBUP_RELEASECAPTURE | (wParam ? LBUP_SELCHANGE : LBUP_RESETSELECTION)); break; case WM_PRINTCLIENT: xxxLBPaint(plb, (HDC) wParam, NULL); break; case WM_PAINT: if (wParam) { hdc = (HDC) wParam; lprc = NULL; } else { hdc = NtUserBeginPaint(hwnd, &ps); lprc = &(ps.rcPaint); } if (IsLBoxVisible(plb)) xxxLBPaint(plb, hdc, lprc); if (!wParam) NtUserEndPaint(hwnd, &ps); break; case WM_NCDESTROY: case WM_FINALDESTROY: xxxDestroyLBox(plb, pwnd); break; case WM_SETFOCUS: // DISABLED in Win 3.1 xxxUpdateWindow(pwnd); CaretCreate(plb); xxxLBSetCaret(plb, TRUE); xxxNotifyOwner(plb, LBN_SETFOCUS); if (FWINABLE()) { if (_IsWindowVisible(pwnd)) { LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase); } } break; case WM_KILLFOCUS: /* * Reset the wheel delta count. */ gcWheelDelta = 0; xxxLBSetCaret(plb, FALSE); xxxCaretDestroy(plb); xxxNotifyOwner(plb, LBN_KILLFOCUS); if (plb->iTypeSearch) { plb->iTypeSearch = 0; NtUserKillTimer(hwnd, IDSYS_LBSEARCH); } if (plb->pszTypeSearch) { UserLocalFree(plb->pszTypeSearch); plb->pszTypeSearch = NULL; } break; case WM_MOUSEWHEEL: { int cDetants; int cPage; int cLines; RECT rc; int windowWidth; int cPos; /* * Don't handle zoom and datazoom. */ if (wParam & (MK_SHIFT | MK_CONTROL)) { goto CallDWP; } lReturn = 1; gcWheelDelta -= (short) HIWORD(wParam); cDetants = gcWheelDelta / WHEEL_DELTA; if ( cDetants != 0 && gpsi->ucWheelScrollLines > 0 && (pwnd->style & (WS_VSCROLL | WS_HSCROLL))) { gcWheelDelta = gcWheelDelta % WHEEL_DELTA; if (pwnd->style & WS_VSCROLL) { cPage = max(1, (plb->cItemFullMax - 1)); cLines = cDetants * (int) min((UINT) cPage, gpsi->ucWheelScrollLines); cPos = max(0, min(plb->iTop + cLines, plb->cMac - 1)); if (cPos != plb->iTop) { xxxLBoxCtlScroll(plb, SB_THUMBPOSITION, cPos); xxxLBoxCtlScroll(plb, SB_ENDSCROLL, 0); } } else if (plb->fMultiColumn) { cPage = max(1, plb->numberOfColumns); cLines = cDetants * (int) min((UINT) cPage, gpsi->ucWheelScrollLines); cPos = max( 0, min((plb->iTop / plb->itemsPerColumn) + cLines, plb->cMac - 1 - ((plb->cMac - 1) % plb->itemsPerColumn))); if (cPos != plb->iTop) { xxxLBoxCtlHScrollMultiColumn(plb, SB_THUMBPOSITION, cPos); xxxLBoxCtlHScrollMultiColumn(plb, SB_ENDSCROLL, 0); } } else { _GetClientRect(plb->spwnd, &rc); windowWidth = rc.right; cPage = max(plb->cxChar, (windowWidth / 3) * 2) / plb->cxChar; cLines = cDetants * (int) min((UINT) cPage, gpsi->ucWheelScrollLines); cPos = max( 0, min(plb->xOrigin + (cLines * plb->cxChar), plb->maxWidth)); if (cPos != plb->xOrigin) { xxxLBoxCtlHScroll(plb, SB_THUMBPOSITION, cPos); xxxLBoxCtlHScroll(plb, SB_ENDSCROLL, 0); } } } } break; case WM_VSCROLL: xxxLBoxCtlScroll(plb, LOWORD(wParam), HIWORD(wParam)); break; case WM_HSCROLL: xxxLBoxCtlHScroll(plb, LOWORD(wParam), HIWORD(wParam)); break; case WM_GETDLGCODE: return DLGC_WANTARROWS | DLGC_WANTCHARS; case WM_CREATE: return xxxLBCreate(plb, pwnd, (LPCREATESTRUCT) lParam); case WM_SETREDRAW: /* * If wParam is nonzero, the redraw flag is set * If wParam is zero, the flag is cleared */ xxxLBSetRedraw(plb, (wParam != 0)); break; case WM_ENABLE: xxxLBInvalidateRect(plb, NULL, !plb->OwnerDraw); break; case WM_SETFONT: xxxLBSetFont(plb, (HANDLE)wParam, LOWORD(lParam)); break; case WM_GETFONT: return (LRESULT)plb->hFont; case WM_DRAGSELECT: case WM_DRAGLOOP: case WM_DRAGMOVE: case WM_DROPFILES: ThreadLock(plb->spwndParent, &tlpwndParent); lReturn = SendMessage(HW(plb->spwndParent), message, wParam, lParam); ThreadUnlock(&tlpwndParent); return lReturn; case WM_QUERYDROPOBJECT: case WM_DROPOBJECT: /* * fix up control data, then pass message to parent */ LBDropObjectHandler(plb, (PDROPSTRUCT)lParam); ThreadLock(plb->spwndParent, &tlpwndParent); lReturn = SendMessage(HW(plb->spwndParent), message, wParam, lParam); ThreadUnlock(&tlpwndParent); return lReturn; case LB_GETITEMRECT: return LBGetItemRect(plb, (INT)wParam, (LPRECT)lParam); case LB_GETITEMDATA: return LBGetItemData(plb, (INT)wParam); // wParam = item index case LB_SETITEMDATA: /* * wParam is item index */ return LBSetItemData(plb, (INT)wParam, lParam); case LB_ADDSTRINGUPPER: wFlags = UPPERCASE | LBI_ADD; goto CallInsertItem; case LB_ADDSTRINGLOWER: wFlags = LOWERCASE | LBI_ADD; goto CallInsertItem; case LB_ADDSTRING: wFlags = LBI_ADD; goto CallInsertItem; case LB_INSERTSTRINGUPPER: wFlags = UPPERCASE; goto CallInsertItem; case LB_INSERTSTRINGLOWER: wFlags = LOWERCASE; goto CallInsertItem; case LB_INSERTSTRING: wFlags = 0; CallInsertItem: lReturn = ((LRESULT) xxxLBInsertItem(plb, (LPWSTR) lParam, (int) wParam, wFlags)); break; case LB_INITSTORAGE: return xxxLBInitStorage(plb, fAnsi, (INT)wParam, (INT)lParam); case LB_DELETESTRING: return xxxLBoxCtlDelete(plb, (INT)wParam); case LB_DIR: /* * wParam - Dos attribute value. * lParam - Points to a file specification string */ lReturn = xxxLbDir(plb, (INT)wParam, (LPWSTR)lParam); break; case LB_ADDFILE: lReturn = xxxLbInsertFile(plb, (LPWSTR)lParam); break; case LB_SETSEL: return xxxLBSetSel(plb, (wParam != 0), (INT)lParam); case LB_SETCURSEL: /* * If window obscured, update so invert will work correctly */ // DISABLED in Win 3.1 xxxUpdateWindow(pwnd); return xxxLBSetCurSel(plb, (INT)wParam); case LB_GETSEL: if (wParam >= (UINT) plb->cMac) return((LRESULT) LB_ERR); return IsSelected(plb, (INT)wParam, SELONLY); case LB_GETCURSEL: if (plb->wMultiple == SINGLESEL) { return plb->iSel; } return plb->iSelBase; case LB_SELITEMRANGE: if (plb->wMultiple == SINGLESEL) { /* * Can't select a range if only single selections are enabled */ RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SELITEMRANGE"); return LB_ERR; } xxxLBSelRange(plb, LOWORD(lParam), HIWORD(lParam), (wParam != 0)); break; case LB_SELITEMRANGEEX: if (plb->wMultiple == SINGLESEL) { /* * Can't select a range if only single selections are enabled */ RIPERR0(ERROR_INVALID_LB_MESSAGE, RIP_VERBOSE,"LB_SELITEMRANGEEX:Can't select a range if only single selections are enabled"); return LB_ERR; } else { BOOL fHighlight = ((DWORD)lParam > (DWORD)wParam); if (fHighlight == FALSE) { ULONG_PTR temp = lParam; lParam = wParam; wParam = temp; } xxxLBSelRange(plb, (INT)wParam, (INT)lParam, fHighlight); } break; case LB_GETTEXTLEN: if (lParam != 0) { RIPMSG1(RIP_WARNING, "LB_GETTEXTLEN with lParam = %lx\n", lParam); } lReturn = LBGetText(plb, TRUE, fAnsi, (INT)wParam, NULL); break; case LB_GETTEXT: lReturn = LBGetText(plb, FALSE, fAnsi, (INT)wParam, (LPWSTR)lParam); break; case LB_GETCOUNT: // Lotus Approach calls CallWndProc(ListWndProc, LB_GETCOUNT,...) // on a window that doesn't have a plb yet. So, we need to make // this check. Bug #6675 - 11/7/94 -- if(plb) return((LRESULT) plb->cMac); else return(0); case LB_SETCOUNT: return xxxLBSetCount(plb, (INT)wParam); case LB_SELECTSTRING: case LB_FINDSTRING: iSel = xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, PREFIX, TRUE); if (message == LB_FINDSTRING || iSel == LB_ERR) { lReturn = iSel; } else { lReturn = xxxLBSetCurSel(plb, iSel); } break; case LB_GETLOCALE: return plb->dwLocaleId; case LB_SETLOCALE: /* * Validate locale */ wParam = ConvertDefaultLocale((LCID)wParam); if (!IsValidLocale((LCID)wParam, LCID_INSTALLED)) return LB_ERR; dw = plb->dwLocaleId; plb->dwLocaleId = (DWORD)wParam; return dw; case WM_KEYDOWN: /* * IanJa: Use LOWORD() to get low 16-bits of wParam - this should * work for Win16 & Win32. The value obtained is the virtual key */ xxxLBoxCtlKeyInput(plb, message, LOWORD(wParam)); break; case WM_CHAR: xxxLBoxCtlCharInput(plb, LOWORD(wParam), fAnsi); break; case LB_GETSELITEMS: case LB_GETSELCOUNT: /* * IanJa/Win32 should this be LPWORD now? */ return LBoxGetSelItems(plb, (message == LB_GETSELCOUNT), (INT)wParam, (LPINT)lParam); case LB_SETTABSTOPS: /* * IanJa/Win32: Tabs given by array of INT for backwards compatability */ return LBSetTabStops(plb, (INT)wParam, (LPINT)lParam); case LB_GETHORIZONTALEXTENT: /* * Return the max width of the listbox used for horizontal scrolling */ return plb->maxWidth; case LB_SETHORIZONTALEXTENT: /* * Set the max width of the listbox used for horizontal scrolling */ if (plb->maxWidth != (INT)wParam) { plb->maxWidth = (INT)wParam; /* * When horizontal extent is set, Show/hide the scroll bars. * NOTE: LBShowHideScrollBars() takes care if Redraw is OFF. * Fix for Bug #2477 -- 01/14/91 -- SANKAR -- */ xxxLBShowHideScrollBars(plb); //Try to show or hide scroll bars if (plb->fHorzBar && plb->fRightAlign && !(plb->fMultiColumn || plb->OwnerDraw)) { /* * origin to right */ xxxLBoxCtlHScroll(plb, SB_BOTTOM, 0); } } break; /* originally returned register ax (message) ! */ case LB_SETCOLUMNWIDTH: /* * Set the width of a column in a multicolumn listbox */ plb->cxColumn = (INT)wParam; LBCalcItemRowsAndColumns(plb); if (IsLBoxVisible(plb)) NtUserInvalidateRect(hwnd, NULL, TRUE); xxxLBShowHideScrollBars(plb); break; case LB_SETANCHORINDEX: if ((INT)wParam >= plb->cMac) { RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SETANCHORINDEX"); return LB_ERR; } plb->iMouseDown = (INT)wParam; plb->iLastMouseMove = (INT)wParam; xxxInsureVisible(plb, (int) wParam, (BOOL)(lParam != 0)); break; case LB_GETANCHORINDEX: return plb->iMouseDown; case LB_SETCARETINDEX: if ( (plb->iSel == -1) || ((plb->wMultiple != SINGLESEL) && (plb->cMac > (INT)wParam))) { /* * Set's the iSelBase to the wParam * if lParam, then don't scroll if partially visible * else scroll into view if not fully visible */ xxxInsureVisible(plb, (INT)wParam, (BOOL)LOWORD(lParam)); xxxSetISelBase(plb, (INT)wParam); break; } else { if ((INT)wParam >= plb->cMac) { RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SETCARETINDEX"); } return LB_ERR; } break; case LB_GETCARETINDEX: return plb->iSelBase; case LB_SETITEMHEIGHT: case LB_GETITEMHEIGHT: return LBGetSetItemHeightHandler(plb, message, (INT)wParam, LOWORD(lParam)); break; case LB_FINDSTRINGEXACT: lReturn = xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, EQ, TRUE); break; case LB_ITEMFROMPOINT: { POINT pt; BOOL bOutside; DWORD dwItem; POINTSTOPOINT(pt, lParam); bOutside = ISelFromPt(plb, pt, &dwItem); UserAssert(bOutside == 1 || bOutside == 0); return (LRESULT)MAKELONG(dwItem, bOutside); } case LBCB_CARETON: /* * Internal message for combo box support */ CaretCreate(plb); // Set up the caret in the proper location for drop downs. plb->iSelBase = plb->iSel; xxxLBSetCaret(plb, TRUE); if (FWINABLE()) { if (_IsWindowVisible(pwnd)) { LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase); } } return(plb->iSel); case LBCB_CARETOFF: /* * Internal message for combo box support */ xxxLBSetCaret(plb, FALSE); xxxCaretDestroy(plb); break; case WM_NCCREATE: if ((pwnd->style & LBS_MULTICOLUMN) && (pwnd->style & WS_VSCROLL)) { DWORD mask = WS_VSCROLL; DWORD flags = 0; if (!TestWF(pwnd, WFWIN40COMPAT)) { mask |= WS_HSCROLL; flags = WS_HSCROLL; } NtUserAlterWindowStyle(hwnd, mask, flags); } goto CallDWP; default: CallDWP: return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi); } /* * Handle translation of ANSI output data and free buffer */ if (lpwsz) { UserLocalFree(lpwsz); } return lReturn; }