Annotation of mstools/samples/sdktools/ddespy/lists.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * LISTS.C
        !             3:  *
        !             4:  * This file implements a generalized multi-collumn listbox with a standard
        !             5:  * frame window.
        !             6:  */
        !             7: #include <windows.h>
        !             8: #include <windowsx.h>
        !             9: #include <string.h>
        !            10: #include <stdlib.h>
        !            11: #include "ddespy.h"
        !            12: #include "globals.h"
        !            13: #include "lists.h"
        !            14: 
        !            15: int  CompareItems(PSTR psz1, PSTR psz2, INT SortCol, INT cCols);
        !            16: int  CmpCols(PSTR psz1, PSTR psz2, INT SortCol);
        !            17: void DrawLBItem(LPDRAWITEMSTRUCT lpdis);
        !            18: long CALLBACK MCLBClientWndProc(HWND hwnd, UINT msg, WPARAM wParam, LONG lPAram);
        !            19: 
        !            20: UINT cyHeading;
        !            21: 
        !            22: HWND CreateMCLBFrame(
        !            23:                     HWND hwndParent,
        !            24:                     LPSTR lpszTitle,        // frame title string
        !            25:                     UINT dwStyle,          // frame styles
        !            26:                     HICON hIcon,
        !            27:                     HBRUSH hbrBkgnd,        // background for heading.
        !            28:                     LPSTR lpszHeadings)     // tab delimited list of headings.  The number of
        !            29:                         // headings indicate the number of collumns.
        !            30: {
        !            31:     static BOOL fRegistered = FALSE;
        !            32:     MCLBCREATESTRUCT mclbcs;
        !            33: 
        !            34:     if (!fRegistered) {
        !            35:         WNDCLASS wc;
        !            36:         HDC hdc;
        !            37:         TEXTMETRIC tm;
        !            38: 
        !            39:         wc.style = WS_OVERLAPPED | CS_HREDRAW | CS_VREDRAW;
        !            40:         wc.lpfnWndProc = MCLBClientWndProc;
        !            41:         wc.cbClsExtra = 0;
        !            42:         wc.cbWndExtra = 4;
        !            43:         wc.hInstance = hInst;
        !            44:         wc.hIcon = hIcon;
        !            45:         wc.hCursor = NULL;
        !            46:         wc.hbrBackground = hbrBkgnd;
        !            47:         wc.lpszMenuName = NULL;
        !            48:         wc.lpszClassName = RefString(IDS_LISTCLASS);
        !            49:         RegisterClass(&wc);
        !            50: 
        !            51:         hdc = GetDC(GetDesktopWindow());
        !            52:         GetTextMetrics(hdc, &tm);
        !            53:         cyHeading = tm.tmHeight;
        !            54:         ReleaseDC(GetDesktopWindow(), hdc);
        !            55: 
        !            56:         fRegistered = TRUE;
        !            57:     }
        !            58:     mclbcs.lpszHeadings = lpszHeadings;
        !            59: 
        !            60:     return(CreateWindow(RefString(IDS_LISTCLASS), lpszTitle, dwStyle,
        !            61:             CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        !            62:             hwndParent, NULL, hInst, (LPSTR)&mclbcs));
        !            63: }
        !            64: 
        !            65: 
        !            66: LONG  CALLBACK MCLBClientWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
        !            67: {
        !            68:     MCLBSTRUCT *pmclb;
        !            69:     RECT rc;
        !            70:     INT  i;
        !            71: 
        !            72:     if (msg == WM_CREATE) {
        !            73:         PSTR psz;
        !            74:         MCLBCREATESTRUCT FAR *pcs;
        !            75: 
        !            76:         pcs = (MCLBCREATESTRUCT FAR *)((LPCREATESTRUCT)lParam)->lpCreateParams;
        !            77:         pmclb = (MCLBSTRUCT *)LocalAlloc(LPTR, sizeof(MCLBSTRUCT));
        !            78:         psz = (PSTR)LocalAlloc(LPTR, _fstrlen(pcs->lpszHeadings) + 1);
        !            79:         _fstrcpy((LPSTR)psz, pcs->lpszHeadings);
        !            80:         pmclb->pszHeadings = psz;
        !            81:         pmclb->cCols = 1;
        !            82:         while ((psz = strchr(psz, '\t'))) {
        !            83:             pmclb->cCols++;
        !            84:             psz++;
        !            85:         }
        !            86:         pmclb->SortCol = 0;
        !            87:         SetWindowLong(hwnd, 0, (UINT)pmclb);
        !            88:         GetClientRect(hwnd, &rc);
        !            89:         pmclb->hwndLB = CreateWindow(RefString(IDS_LBOX), szNULL, MYLBSTYLE | WS_VISIBLE,
        !            90:                 0, 0, 0, 0, hwnd, (HMENU)pmclb->cCols, hInst, NULL);
        !            91:         return(pmclb->hwndLB ? 0 : -1);
        !            92:     }
        !            93: 
        !            94:     pmclb = (MCLBSTRUCT *)GetWindowLong(hwnd, 0);
        !            95: 
        !            96:     switch (msg) {
        !            97:     case WM_PAINT:
        !            98:         {
        !            99:             PAINTSTRUCT ps;
        !           100:             DRAWITEMSTRUCT dis;
        !           101: 
        !           102:             BeginPaint(hwnd, &ps);
        !           103:             SetBkMode(ps.hdc, TRANSPARENT);
        !           104:             dis.hwndItem = hwnd;
        !           105:             dis.hDC = ps.hdc;
        !           106:             GetClientRect(hwnd, &dis.rcItem);
        !           107:             dis.rcItem.bottom = dis.rcItem.top + cyHeading;
        !           108:             dis.CtlType = ODT_BUTTON;   // hack to avoid erasure
        !           109:             dis.CtlID = pmclb->cCols;
        !           110:             dis.itemID = 0;
        !           111:             dis.itemAction = ODA_DRAWENTIRE;
        !           112:             dis.itemData = (UINT)(LPSTR)pmclb->pszHeadings;
        !           113:             dis.itemState = 0;
        !           114:             DrawLBItem(&dis);
        !           115:             EndPaint(hwnd, &ps);
        !           116:         }
        !           117:         break;
        !           118: 
        !           119:     case WM_SIZE:
        !           120:         MoveWindow(pmclb->hwndLB, 0, cyHeading, LOWORD(lParam),
        !           121:                 HIWORD(lParam) - cyHeading, TRUE);
        !           122:         break;
        !           123: 
        !           124:     case WM_LBUTTONDOWN:
        !           125:         {
        !           126:             HWND hwndLB;
        !           127:             INT i;
        !           128: 
        !           129:             // determine which collumn the mouse landed and sort on that collumn.
        !           130: 
        !           131:             SendMessage(hwnd, WM_SETREDRAW, 0, 0);
        !           132:             GetClientRect(hwnd, &rc);
        !           133:             InflateRect(&rc, -1, -1);
        !           134:             pmclb->SortCol = LOWORD(lParam) * pmclb->cCols / (rc.right - rc.left);
        !           135:             hwndLB = CreateWindow(RefString(IDS_LBOX), szNULL, MYLBSTYLE, 1, cyHeading + 1,
        !           136:                     rc.right - rc.left, rc.bottom - rc.top - cyHeading,
        !           137:                     hwnd, (HMENU)pmclb->cCols, hInst, NULL);
        !           138:             for (i = (INT)SendMessage(pmclb->hwndLB, LB_GETCOUNT, 0, 0); i; i--) {
        !           139:                 SendMessage(hwndLB, LB_ADDSTRING, 0,
        !           140:                     SendMessage(pmclb->hwndLB, LB_GETITEMDATA, i - 1, 0));
        !           141:                 SendMessage(pmclb->hwndLB, LB_SETITEMDATA, i - 1, 0);
        !           142:             }
        !           143:             ShowWindow(hwndLB, SW_SHOW);
        !           144:             ShowWindow(pmclb->hwndLB, SW_HIDE);
        !           145:             DestroyWindow(pmclb->hwndLB);
        !           146:             pmclb->hwndLB = hwndLB;
        !           147:             SendMessage(hwnd, WM_SETREDRAW, 1, 0);
        !           148:             InvalidateRect(hwnd, NULL, FALSE);
        !           149:         }
        !           150:         break;
        !           151: 
        !           152:     case WM_DELETEITEM:
        !           153: 
        !           154:         if ((UINT)((LPDELETEITEMSTRUCT)lParam)->itemData)
        !           155:             LocalFree(LocalHandle((PVOID)((LPDELETEITEMSTRUCT)lParam)->itemData));
        !           156:         break;
        !           157: 
        !           158:     case WM_MEASUREITEM:
        !           159:         ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = cyHeading;
        !           160:         break;
        !           161: 
        !           162:     case WM_DRAWITEM:
        !           163:         GetClientRect(hwnd, &rc);
        !           164:         // This fudge makes the collumns line up with the heading.
        !           165:         ((LPDRAWITEMSTRUCT)lParam)->rcItem.right = rc.right;
        !           166:         DrawLBItem((LPDRAWITEMSTRUCT)lParam);
        !           167:         return(DefWindowProc(hwnd, msg, wParam, lParam));
        !           168:         break;
        !           169: 
        !           170:     case WM_COMPAREITEM:
        !           171:         return(CompareItems((PSTR)((LPCOMPAREITEMSTRUCT)lParam)->itemData1,
        !           172:                 (PSTR)((LPCOMPAREITEMSTRUCT)lParam)->itemData2,
        !           173:                 pmclb->SortCol,
        !           174:                 pmclb->cCols));
        !           175:         break;
        !           176: 
        !           177:     case WM_DESTROY:
        !           178:         LocalFree(LocalHandle((PVOID)pmclb->pszHeadings));
        !           179:         LocalFree(LocalHandle((PVOID)pmclb));
        !           180:         break;
        !           181: 
        !           182:     case WM_CLOSE:
        !           183:         for (i = 0; i < IT_COUNT && (hwndTrack[i] != hwnd); i++) {
        !           184:             ;
        !           185:         }
        !           186:         pro.fTrack[i] = FALSE;
        !           187:         hwndTrack[i] = NULL;
        !           188:         SetFilters();
        !           189:         DestroyWindow(hwnd);
        !           190:         break;
        !           191: 
        !           192:     default:
        !           193:         return(DefWindowProc(hwnd, msg, wParam, lParam));
        !           194:     }
        !           195: }
        !           196: 
        !           197: 
        !           198: 
        !           199: 
        !           200: /*
        !           201:  * Make this return FALSE if addition not needed.
        !           202:  *
        !           203:  * if pszSearch != NULL, searches for pszSearch - collumns may contain
        !           204:  * wild strings - "*"
        !           205:  * If found, the string is removed from the LB.
        !           206:  * Adds pszReplace to LB.
        !           207:  */
        !           208: VOID AddMCLBText(PSTR pszSearch, PSTR pszReplace, HWND hwndLBFrame)
        !           209: {
        !           210:     MCLBSTRUCT *pmclb;
        !           211:     INT lit;
        !           212:     PSTR psz;
        !           213: 
        !           214:     pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
        !           215: 
        !           216:     SendMessage(pmclb->hwndLB, WM_SETREDRAW, 0, 0);
        !           217:     if (pszSearch != NULL) {
        !           218:         lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1, (LONG)(LPSTR)pszSearch);
        !           219:         if (lit >= 0) {
        !           220:             SendMessage(pmclb->hwndLB, LB_DELETESTRING, lit, 0);
        !           221:         }
        !           222:     }
        !           223:     psz = (PSTR)LocalAlloc(LPTR, strlen(pszReplace) + 1);
        !           224:     strcpy(psz, pszReplace);
        !           225:     SendMessage(pmclb->hwndLB, WM_SETREDRAW, 1, 0);
        !           226:     SendMessage(pmclb->hwndLB, LB_ADDSTRING, 0, (LONG)(LPSTR)psz);
        !           227: }
        !           228: 
        !           229: 
        !           230: /*
        !           231:  * This function assumes that the text in cCol is an ASCII number.  0 is
        !           232:  * returned if it is not found.
        !           233:  */
        !           234: INT GetMCLBColValue(PSTR pszSearch, HWND hwndLBFrame, INT  cCol)
        !           235: {
        !           236:     MCLBSTRUCT *pmclb;
        !           237:     PSTR psz;
        !           238:     INT lit;
        !           239: 
        !           240:     pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
        !           241: 
        !           242:     lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1, (LONG)(LPSTR)pszSearch);
        !           243:     if (lit < 0) {
        !           244:         return(0);
        !           245:     }
        !           246:     psz = (PSTR)SendMessage(pmclb->hwndLB, LB_GETITEMDATA, lit, 0);
        !           247:     while (--cCol && (psz = strchr(psz, '\t') + 1)) {
        !           248:         ;
        !           249:     }
        !           250:     if (psz) {
        !           251:         return(atoi(psz));
        !           252:     } else {
        !           253:         return(0);
        !           254:     }
        !           255: }
        !           256: 
        !           257: 
        !           258: 
        !           259: /*
        !           260:  * Returns fFoundAndRemoved
        !           261:  */
        !           262: BOOL DeleteMCLBText(PSTR pszSearch, HWND hwndLBFrame)
        !           263: {
        !           264:     MCLBSTRUCT *pmclb;
        !           265:     INT lit;
        !           266: 
        !           267:     pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
        !           268:     lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1,
        !           269:             (LONG)(LPSTR)pszSearch);
        !           270:     if (lit >= 0) {
        !           271:         SendMessage(pmclb->hwndLB, LB_DELETESTRING, lit, 0);
        !           272:         return(TRUE);
        !           273:     }
        !           274:     return(FALSE);
        !           275: }
        !           276: 
        !           277: 
        !           278: /*
        !           279:  * Returns >0 if item1 comes first, <0 if item2 comes first, 0 if ==.
        !           280:  */
        !           281: INT CompareItems(PSTR psz1, PSTR psz2, INT SortCol, INT cCols)
        !           282: {
        !           283:     INT i, Col;
        !           284: 
        !           285:     i = CmpCols(psz1, psz2, SortCol);
        !           286:     if (i != 0) {
        !           287:         return(i);
        !           288:     }
        !           289:     for (Col = 0; Col < cCols; Col++) {
        !           290:         if (Col == SortCol) {
        !           291:             continue;
        !           292:         }
        !           293:         i = CmpCols(psz1, psz2, Col);
        !           294:         if (i != 0) {
        !           295:             return(i);
        !           296:         }
        !           297:     }
        !           298:     return(0);
        !           299: }
        !           300: 
        !           301: 
        !           302: INT CmpCols(PSTR psz1, PSTR psz2, INT SortCol)
        !           303: {
        !           304:     PSTR psz, pszT1, pszT2;
        !           305:     INT iRet;
        !           306: 
        !           307:     while (SortCol--) {
        !           308:         psz = strchr(psz1, '\t');
        !           309:         if (psz != NULL) {
        !           310:             psz1 = psz + 1;
        !           311:         } else {
        !           312:             psz1 = psz1 + strlen(psz1);
        !           313:         }
        !           314:         psz = strchr(psz2, '\t');
        !           315:         if (psz != NULL) {
        !           316:             psz2 = psz + 1;
        !           317:         } else {
        !           318:             psz2 = psz2 + strlen(psz2);
        !           319:         }
        !           320:     }
        !           321:     pszT1 = strchr(psz1, '\t');
        !           322:     pszT2 = strchr(psz2, '\t');
        !           323: 
        !           324:     if (pszT1) {
        !           325:         *pszT1 = '\0';
        !           326:     }
        !           327:     if (pszT2) {
        !           328:         *pszT2 = '\0';
        !           329:     }
        !           330: 
        !           331:     if (!strcmp(RefString(IDS_WILD), psz1) || !strcmp(RefString(IDS_WILD), psz2)) {
        !           332:         iRet = 0;
        !           333:     } else {
        !           334:         iRet = strcmp(psz1, psz2);
        !           335:     }
        !           336: 
        !           337:     if (pszT1) {
        !           338:         *pszT1 = '\t';
        !           339:     }
        !           340:     if (pszT2) {
        !           341:         *pszT2 = '\t';
        !           342:     }
        !           343: 
        !           344:     return(iRet);
        !           345: }
        !           346: 
        !           347: 
        !           348: 
        !           349: VOID DrawLBItem(LPDRAWITEMSTRUCT lpdis)
        !           350: {
        !           351:     RECT rcDraw;
        !           352:     INT cxSection;
        !           353:     PSTR psz, pszEnd;
        !           354: 
        !           355:     if (!lpdis->itemData)
        !           356:         return;
        !           357:     if ((lpdis->itemAction & ODA_DRAWENTIRE) ||
        !           358:             ((lpdis->itemAction & ODA_SELECT) &&
        !           359:             (lpdis->itemState & ODS_SELECTED))) {
        !           360:         rcDraw = lpdis->rcItem;
        !           361:         if (lpdis->CtlType != ODT_BUTTON) { // hack to avoid erasure
        !           362:             HBRUSH hbr;
        !           363: 
        !           364:             hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
        !           365:             FillRect(lpdis->hDC, &lpdis->rcItem, hbr);
        !           366:             DeleteObject(hbr);
        !           367:         }
        !           368:         cxSection = (rcDraw.right - rcDraw.left) / lpdis->CtlID;
        !           369:         psz = (PSTR)(UINT)lpdis->itemData;
        !           370:         rcDraw.right = rcDraw.left + cxSection;
        !           371:         while (pszEnd = strchr(psz, '\t')) {
        !           372:             *pszEnd = '\0';
        !           373:             DrawText(lpdis->hDC, psz, -1, &rcDraw, DT_LEFT);
        !           374:             OffsetRect(&rcDraw, cxSection, 0);
        !           375:             *pszEnd = '\t';
        !           376:             psz = pszEnd + 1;
        !           377:         }
        !           378:         DrawText(lpdis->hDC, psz, -1, &rcDraw, DT_LEFT);
        !           379: 
        !           380:         if (lpdis->itemState & ODS_SELECTED)
        !           381:             InvertRect(lpdis->hDC, &lpdis->rcItem);
        !           382: 
        !           383:         if (lpdis->itemState & ODS_FOCUS)
        !           384:             DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
        !           385: 
        !           386:     } else if (lpdis->itemAction & ODA_SELECT) {
        !           387: 
        !           388:         InvertRect(lpdis->hDC, &lpdis->rcItem);
        !           389: 
        !           390:     } else if (lpdis->itemAction & ODA_FOCUS) {
        !           391: 
        !           392:         DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
        !           393: 
        !           394:     }
        !           395: }
        !           396: 
        !           397: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.