📄 listbox.c
字号:
/* Copyright (C) 2004-2005 Li Yudong*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "../include/common.h"#include "../include/listbox.h"#include "../include/regclass.h"#include "../include/hdc.h"#include "../include/gdi.h"#include "../include/rect.h"#include "../include/message.h"#include "../include/blockheap.h"#include "../include/invalidregion.h"#include "../include/clipregion.h"#include "../include/caret.h"#include "../include/winnc.h"#include "../include/winbase.h"#include "../include/window.h"#include "../include/text.h"#include "../include/scrollbar.h"//==================================static BOOLlstIsNofity( HWND hWnd);static BOOL lstInitListBoxData( LISTBOXDATA* pData, int len);static void lstListBoxCleanUp( LISTBOXDATA* pData);static void lstResetListBoxContent( PLISTBOXDATA pData);static PLISTBOXITEM lstAllocItem ( PLISTBOXDATA pData);static void lstFreeItem( PLISTBOXDATA pData, PLISTBOXITEM plbi);static int lstAddNewItem( DWORD dwStyle, PLISTBOXDATA pData, PLISTBOXITEM newItem, int pos);static PLISTBOXITEM lstRemoveItem( PLISTBOXDATA pData, int* pos);static PLISTBOXITEM lstGetItem( PLISTBOXDATA pData, int pos);static int lstFindItem( PLISTBOXDATA pData, int start, char* key, BOOL bExact);static BOOL lstInvalidateUnderItem( HWND hwnd, PLISTBOXDATA pData, int pos);static void lstGetItemsRect( PLISTBOXDATA pData, int start, int end, RECT* prc);static void lstSetVScrollInfo( HWND hwnd, PLISTBOXDATA pData, BOOL fRedraw);//==============================================================BOOL RegisterListBoxControl(){ WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = 0; wcex.lpfnWndProc = (WNDPROC)ListBoxCtrlProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = 0; wcex.hIcon = 0; wcex.hCursor = 0; wcex.hbrBackground = CreateSolidBrush(RGB(198,239,229)); wcex.lpszMenuName = NULL; wcex.lpszClassName = "listbox"; wcex.hIconSm = 0; RegisterClass(&wcex); return true;}LRESULT ListBoxCtrlProc( HWND hWnd, int iMsg, WPARAM wParam, LPARAM lParam){ RECT rc,rcItem,rcItemHilighted; HDC hDC; PAINTSTRUCT ps; int iWidth,iHeight; HPEN hPen; HBRUSH hBrush; COLORREF crColor; PWNDCLASSEX pWndClass; LRESULT res; PLISTBOXDATA pData; PLISTBOXITEM removed; PWindowsTree pWin; int delete; DWORD dwStyle; char* string = NULL; char* pFileName; int iCounter,iTotal; PLISTBOXITEM plbi = NULL; PLISTBOXITEM newItem; int pos; int x,y; pWin=(PWindowsTree)hWnd; switch(iMsg) { case LMSG_CREATE: pData = (PLISTBOXDATA)malloc(sizeof(LISTBOXDATA)); if(!pData) return false; memset(pData,0, sizeof(LISTBOXDATA)); pWin->dwData = (DWORD)pData; //dwAddData save background bmp file path pFileName = (char*)malloc(strlen((char*)lParam)+1); strcpy(pFileName,(char*)lParam); pWin->dwAddData = (DWORD)pFileName; if(!lstInitListBoxData(pData,DEF_LB_BUFFER_LEN)) return false; break; case LMSG_ACTIVEWINDOW: break; case LMSG_COMMAND: break; case LMSG_PENDOWN: { int oldSel,hit; pData = (PLISTBOXDATA)(pWin->dwData); GetClientRect(hWnd,&rc); ScreenToClientRect(hWnd,&rc); x = (int)wParam; y = (int)lParam; ScreenToClient(hWnd,&x,&y); hit = y / pData->itemHeight; hit += pData->itemTop; if (hit >= pData->itemCount) break; oldSel = pData->itemHilighted; iTotal =pData->itemVisibles; for(iCounter=0;iCounter<iTotal;iCounter++){ plbi=lstGetItem(pData,pData->itemTop + iCounter); lstGetItemsRect(pData,pData->itemTop+iCounter,pData->itemTop+iCounter,&rcItem); rcItem.left=rc.left; rcItem.right =rc.right; if(PtInRect(&rcItem,x,y)){ lstGetItemsRect(pData,pData->itemHilighted,pData->itemHilighted,&rcItemHilighted); rcItemHilighted.left=rc.left; rcItemHilighted.right =rc.right; pData->itemHilighted = pData->itemTop + iCounter; InvalidateRect(hWnd,&rcItemHilighted,false); InvalidateRect(hWnd,&rcItem,false); break; } } if (oldSel != hit && lstIsNofity(hWnd)) NotifyParent(hWnd, LBN_SELCHANGE); } break; case LMSG_PENUP: break; case LMSG_PENMOVE: break; case LMSG_ERASEBKGND: pWndClass=GetRegClass(pWin->lpszClassName); if(!pWndClass) return (LRESULT)NULL; hBrush=pWndClass->hbrBackground; crColor=((BRUSH*)hBrush)->crBrushColor; ((BRUSH*)hBrush)->crBrushColor=RGB_SYSTEMHIBRIGHT; res=DefWindowProc(hWnd, iMsg, wParam, lParam); ((BRUSH*)hBrush)->crBrushColor=crColor; return res; case LMSG_ENABLE: break; case LMSG_PAINT: ps.bPaintDirect=false; hDC=BeginPaint(hWnd, &ps); if(!hDC){ return true; } //GetClientRect(hWnd,&rc); scrGetClientRect(hWnd,&rc); ScreenToClientRect(hWnd,&rc); if(pWin->dwAddData) ShowBitmap(hDC,0,0,(char*)(pWin->dwAddData)); iWidth =rc.right - rc.left + 1; iHeight =rc.bottom - rc.top + 1; pData = (PLISTBOXDATA)(pWin->dwData); if(!pData) return false; iTotal =pData->itemVisibles; //printf("%d\n",pData->itemTop); for(iCounter=0;iCounter<iTotal;iCounter++){ plbi=lstGetItem(pData,pData->itemTop + iCounter); lstGetItemsRect(pData,pData->itemTop+iCounter,pData->itemTop+iCounter,&rcItem); rcItem.left=rc.left; rcItem.right =rc.right; if(iCounter + pData->itemTop == pData->itemHilighted) FillRectangle(hDC,rcItem.left,rcItem.top,rcItem.right,rcItem.bottom,RGB_SYSTEMBRIGHT,RGB_SYSTEMBRIGHT); DrawText(hDC,plbi->key,strlen(plbi->key),&rcItem,DT_CENTER); } EndPaint(hWnd, &ps); break; case LMSG_DESTROY: pData = (PLISTBOXDATA)(pWin->dwData); lstListBoxCleanUp (pData); free (pData); if(pWin->dwAddData) free((char*)(pWin->dwAddData)); break; case LB_RESETCONTENT: pData = (PLISTBOXDATA)(pWin->dwData); lstResetListBoxContent (pData); winInvalidateRect (hWnd, NULL, TRUE); break; case LB_ADDSTRING: case LB_INSERTSTRING: string = (char*)lParam; if (string == NULL || string [0] == '\0') return false; pData = (PLISTBOXDATA)(pWin->dwData); newItem = lstAllocItem (pData); newItem->key = strdup (string); if (!newItem->key) { lstFreeItem (pData, newItem); printerror("alloc memory error!"); return false; } newItem->dwFlags = LBIF_NORMAL; newItem->dwAddData = 0L; if (iMsg == LB_ADDSTRING) pos = lstAddNewItem (dwStyle, pData, newItem, -1); else pos = lstAddNewItem (dwStyle, pData, newItem, (int)wParam); //modify visible items GetClientRect(hWnd,&rc); iHeight =rc.bottom - rc.top + 1; if(pData->itemVisibles < iHeight/pData->itemHeight) pData->itemVisibles +=1; lstInvalidateUnderItem (hWnd, pData, pos); lstSetVScrollInfo (hWnd, pData, TRUE); return true; case LB_DELETESTRING: delete = (int)wParam; pData = (PLISTBOXDATA)(pWin->dwData); removed = lstRemoveItem (pData, &delete); if (removed){ free (removed->key); lstFreeItem (pData, removed); pData->itemCount --; if (pData->itemTop != 0 && pData->itemCount <= pData->itemVisibles){ pData->itemTop = 0; winInvalidateRect (hWnd, NULL, TRUE); } else{ lstInvalidateUnderItem (hWnd, pData, delete); if (delete <= pData->itemTop){ pData->itemTop --; if (pData->itemTop < 0) pData->itemTop = 0; } } if (pData->itemHilighted >= pData->itemCount){ pData->itemHilighted = pData->itemCount - 1; if (pData->itemHilighted < 0) pData->itemHilighted = 0; } if (pData->itemHilighted < pData->itemTop) pData->itemHilighted = pData->itemTop; if (pData->itemHilighted > ITEM_BOTTOM (pData)) pData->itemHilighted = ITEM_BOTTOM (pData); lstSetVScrollInfo (hWnd, pData, TRUE); return 0; } else return false; break; case LB_FINDSTRING: if( *(char*)lParam == '\0' ) return false; pData = (PLISTBOXDATA)(pWin->dwData); return lstFindItem(pData, (int)wParam, (char*)lParam, FALSE); case LB_FINDSTRINGEXACT: if( *(char*)lParam == '\0' ) return false; pData = (PLISTBOXDATA)(pWin->dwData); return lstFindItem(pData, (int)wParam, (char*)lParam, TRUE); case LB_GETCOUNT: return pData->itemCount; case LB_SETCURSEL: { int new = (int)wParam; int old, newTop; pData = (PLISTBOXDATA)(pWin->dwData); if (new < 0 || new > pData->itemCount - 1) return LB_ERR; old = pData->itemHilighted; if (new >= 0 && new != old){ if (pData->itemCount - new >= pData->itemVisibles) newTop = new; else newTop = max (pData->itemCount - pData->itemVisibles, 0); pData->itemTop = newTop; pData->itemHilighted = new; lstSetVScrollInfo (hWnd, pData, TRUE); } InvalidateRect (hWnd, NULL, TRUE); return old; } case LB_GETCURSEL: { PLISTBOXITEM plbi; int index = 0; pData = (PLISTBOXDATA)(pWin->dwData); plbi = pData->head; while(plbi){ if (plbi->dwFlags & LBIF_SELECTED) return index; index ++; plbi = plbi->next; } return LB_ERR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -