Annotation of mstools/samples/sdktools/ddespy/lists.c, revision 1.1.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.