VLISTVW.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:18k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /**************************************************************************
  2.    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3.    ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4.    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5.    PARTICULAR PURPOSE.
  6.    Copyright 1997 Microsoft Corporation.  All Rights Reserved.
  7. **************************************************************************/
  8. /**************************************************************************
  9.    Include Files
  10. **************************************************************************/
  11. #define STRICT
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <commctrl.h>
  15. #include "VListVw.h"
  16. /**************************************************************************
  17.    Local Function Prototypes
  18. **************************************************************************/
  19. #define ErrorHandler() ErrorHandlerEx(__LINE__, __FILE__)
  20. void ErrorHandlerEx(WORD, LPSTR);
  21. LRESULT ListViewNotify(HWND, LPARAM);
  22. void SwitchView(HWND, DWORD);
  23. BOOL DoContextMenu(HWND, WPARAM, LPARAM);
  24. void UpdateMenu(HWND, HMENU);
  25. BOOL InsertListViewItems(HWND);
  26. void PositionHeader(HWND);
  27. /**************************************************************************
  28.    Global Variables
  29. **************************************************************************/
  30. HANDLE   g_hInst;
  31. TCHAR    g_szClassName[] = TEXT("VListVwClass");
  32. #define ITEM_COUNT   100000
  33. /******************************************************************************
  34.    WinMain
  35. ******************************************************************************/
  36. int PASCAL WinMain(  HINSTANCE hInstance,
  37.                      HINSTANCE hPrevInstance,
  38.                      LPSTR lpCmdLine,
  39.                      int nCmdShow)
  40. {
  41. MSG  msg;
  42. g_hInst = hInstance;
  43. if(!hPrevInstance)
  44.    if(!InitApplication(hInstance))
  45.       return FALSE;
  46. //required to use the common controls
  47. InitCommonControls();
  48. /* Perform initializations that apply to a specific instance */
  49. if (!InitInstance(hInstance, nCmdShow))
  50.    return FALSE;
  51. /* Acquire and dispatch messages until a WM_QUIT uMessage is received. */
  52. while(GetMessage( &msg, NULL, 0x00, 0x00))
  53.    {
  54.    TranslateMessage(&msg);
  55.    DispatchMessage(&msg);
  56.    }
  57. return msg.wParam;
  58. }
  59. /******************************************************************************
  60.    InitApplication
  61. ******************************************************************************/
  62. BOOL InitApplication(HINSTANCE hInstance)
  63. {
  64. WNDCLASSEX  wcex;
  65. ATOM        aReturn;
  66. wcex.cbSize          = sizeof(WNDCLASSEX);
  67. wcex.style           = 0;
  68. wcex.lpfnWndProc     = (WNDPROC)MainWndProc;
  69. wcex.cbClsExtra      = 0;
  70. wcex.cbWndExtra      = 0;
  71. wcex.hInstance       = hInstance;
  72. wcex.hCursor         = LoadCursor(NULL, IDC_ARROW);
  73. wcex.hbrBackground   = (HBRUSH)(COLOR_WINDOW + 1);
  74. wcex.lpszMenuName    = MAKEINTRESOURCE(IDM_MAIN_MENU);
  75. wcex.lpszClassName   = g_szClassName;
  76. wcex.hIcon           = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_MAINICON));
  77. wcex.hIconSm         = LoadImage(g_hInst, MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, 16, 16, 0);
  78. aReturn = RegisterClassEx(&wcex);
  79. if(0 == aReturn)
  80.    {
  81.    WNDCLASS wc;
  82.    wc.style          = 0;
  83.    wc.lpfnWndProc    = (WNDPROC)MainWndProc;
  84.    wc.cbClsExtra     = 0;
  85.    wc.cbWndExtra     = 0;
  86.    wc.hInstance      = hInstance;
  87.    wc.hIcon          = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_MAINICON));
  88.    wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  89.    wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  90.    wc.lpszMenuName   = MAKEINTRESOURCE(IDM_MAIN_MENU);
  91.    wc.lpszClassName  = g_szClassName;
  92.    aReturn = RegisterClass(&wc);
  93.    }
  94. return aReturn;
  95. }
  96. /******************************************************************************
  97.    InitInstance
  98. ******************************************************************************/
  99. BOOL InitInstance(   HINSTANCE hInstance,
  100.                      int nCmdShow)
  101. {
  102. HWND     hWnd;
  103. TCHAR    szTitle[MAX_PATH] = "";
  104. g_hInst = hInstance;
  105. LoadString(g_hInst, IDS_APPTITLE, szTitle, sizeof(szTitle));
  106. /* Create a main window for this application instance.  */
  107. hWnd = CreateWindowEx(  0,
  108.                         g_szClassName,
  109.                         szTitle,
  110.                         WS_OVERLAPPEDWINDOW,
  111.                         CW_USEDEFAULT,
  112.                         CW_USEDEFAULT,
  113.                         CW_USEDEFAULT,
  114.                         CW_USEDEFAULT,
  115.                         NULL,
  116.                         NULL,
  117.                         hInstance,
  118.                         NULL);
  119. /* If window could not be created, return "failure" */
  120. if (!hWnd)
  121.    return FALSE;
  122. /* Make the window visible; update its client area; and return "success" */
  123. ShowWindow(hWnd, nCmdShow);
  124. UpdateWindow(hWnd);
  125. return TRUE;
  126. }
  127. /******************************************************************************
  128.    MainWndProc
  129. ******************************************************************************/
  130. LRESULT CALLBACK MainWndProc( HWND hWnd,
  131.                               UINT uMessage,
  132.                               WPARAM wParam,
  133.                               LPARAM lParam)
  134. {
  135. static HWND hwndListView;
  136. switch (uMessage)
  137.    {
  138.    case WM_CREATE:
  139.       // create the TreeView control
  140.       hwndListView = CreateListView(g_hInst, hWnd);
  141.       
  142.       //initialize the TreeView control
  143.       InitListView(hwndListView);
  144.       
  145.       break;
  146.    case WM_NOTIFY:
  147.       return ListViewNotify(hWnd, lParam);
  148.    
  149.    case WM_SIZE:
  150.       ResizeListView(hwndListView, hWnd);
  151.       break;
  152.    case WM_INITMENUPOPUP:
  153.       UpdateMenu(hwndListView, GetMenu(hWnd));
  154.       break;
  155.    
  156.    case WM_CONTEXTMENU:
  157.       if(DoContextMenu(hWnd, wParam, lParam))
  158.          return FALSE;
  159.       break;
  160.    
  161.    case WM_COMMAND:
  162.       switch (GET_WM_COMMAND_ID(wParam, lParam))
  163.          {
  164.          case IDM_LARGE_ICONS:
  165.             SwitchView(hwndListView, LVS_ICON);
  166.             break;
  167.          
  168.          case IDM_SMALL_ICONS:
  169.             SwitchView(hwndListView, LVS_SMALLICON);
  170.             break;
  171.          
  172.          case IDM_LIST:
  173.             SwitchView(hwndListView, LVS_LIST);
  174.             break;
  175.          
  176.          case IDM_REPORT:
  177.             SwitchView(hwndListView, LVS_REPORT);
  178.             break;
  179.          
  180.          case IDM_EXIT:
  181.             DestroyWindow(hWnd);
  182.             break;
  183.          
  184.          case IDM_ABOUT:
  185.             DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, AboutDlgProc);
  186.             break;   
  187.          }
  188.       break;
  189.    case WM_DESTROY:
  190.       PostQuitMessage(0);
  191.       break;
  192.    default:
  193.       break;
  194.    }
  195. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  196. }
  197. /******************************************************************************
  198.    AboutDlgProc
  199. ******************************************************************************/
  200. BOOL CALLBACK AboutDlgProc(   HWND hDlg, 
  201.                               UINT uMessage, 
  202.                               WPARAM wParam, 
  203.                               LPARAM lParam)
  204. {
  205. switch (uMessage)
  206.    {
  207.    case WM_INITDIALOG:
  208.       return TRUE;
  209.       
  210.    case WM_COMMAND:
  211.       switch(wParam)
  212.          {
  213.          case IDOK:
  214.             EndDialog(hDlg, IDOK);
  215.             break;
  216.          case IDCANCEL:
  217.             EndDialog(hDlg, IDOK);
  218.             break;
  219.          }
  220.       return TRUE;
  221.     } 
  222.     
  223. return FALSE;
  224. }
  225. /******************************************************************************
  226.    CreateListView
  227. ******************************************************************************/
  228. HWND CreateListView(HINSTANCE hInstance, HWND hwndParent)
  229. {
  230. DWORD       dwStyle;
  231. HWND        hwndListView;
  232. HIMAGELIST  himlSmall;
  233. HIMAGELIST  himlLarge;
  234. BOOL        bSuccess = TRUE;
  235. dwStyle =   WS_TABSTOP | 
  236.             WS_CHILD | 
  237.             WS_BORDER | 
  238.             WS_VISIBLE |
  239.             LVS_AUTOARRANGE |
  240.             LVS_REPORT | 
  241.             LVS_OWNERDATA;
  242.             
  243. hwndListView = CreateWindowEx(   WS_EX_CLIENTEDGE,          // ex style
  244.                                  WC_LISTVIEW,               // class name - defined in commctrl.h
  245.                                  "",                        // dummy text
  246.                                  dwStyle,                   // style
  247.                                  0,                         // x position
  248.                                  0,                         // y position
  249.                                  0,                         // width
  250.                                  0,                         // height
  251.                                  hwndParent,                // parent
  252.                                  (HMENU)ID_LISTVIEW,        // ID
  253.                                  g_hInst,                   // instance
  254.                                  NULL);                     // no extra data
  255. if(!hwndListView)
  256.    return NULL;
  257. ResizeListView(hwndListView, hwndParent);
  258. //set the image lists
  259. himlSmall = ImageList_Create(16, 16, ILC_COLORDDB | ILC_MASK, 1, 0);
  260. himlLarge = ImageList_Create(32, 32, ILC_COLORDDB | ILC_MASK, 1, 0);
  261. if (himlSmall && himlLarge)
  262.    {
  263.    HICON hIcon;
  264.    //set up the small image list
  265.    hIcon = LoadImage(g_hInst, MAKEINTRESOURCE(IDI_DISK), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
  266.    ImageList_AddIcon(himlSmall, hIcon);
  267.    //set up the large image list
  268.    hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_DISK));
  269.    ImageList_AddIcon(himlLarge, hIcon);
  270.    ListView_SetImageList(hwndListView, himlSmall, LVSIL_SMALL);
  271.    ListView_SetImageList(hwndListView, himlLarge, LVSIL_NORMAL);
  272.    }
  273. return hwndListView;
  274. }
  275. /******************************************************************************
  276.    ResizeListView
  277. ******************************************************************************/
  278. void ResizeListView(HWND hwndListView, HWND hwndParent)
  279. {
  280. RECT  rc;
  281. GetClientRect(hwndParent, &rc);
  282. MoveWindow( hwndListView, 
  283.             rc.left,
  284.             rc.top,
  285.             rc.right - rc.left,
  286.             rc.bottom - rc.top,
  287.             TRUE);
  288. //only call this if we want the LVS_NOSCROLL style
  289. //PositionHeader(hwndListView);
  290. }
  291. /******************************************************************************
  292.    PositionHeader
  293.    this needs to be called when the ListView is created, resized, the view is 
  294.    changed or a WM_SYSPARAMETERCHANGE message is recieved
  295. ******************************************************************************/
  296. void PositionHeader(HWND hwndListView)
  297. {
  298. HWND  hwndHeader = GetWindow(hwndListView, GW_CHILD);
  299. DWORD dwStyle = GetWindowLong(hwndListView, GWL_STYLE);
  300. /*To ensure that the first item will be visible, create the control without 
  301. the LVS_NOSCROLL style and then add it here*/
  302. dwStyle |= LVS_NOSCROLL;
  303. SetWindowLong(hwndListView, GWL_STYLE, dwStyle);
  304. //only do this if we are in report view and were able to get the header hWnd
  305. if(((dwStyle & LVS_TYPEMASK) == LVS_REPORT) && hwndHeader)
  306.    {
  307.    RECT        rc;
  308.    HD_LAYOUT   hdLayout;
  309.    WINDOWPOS   wpos;
  310.    GetClientRect(hwndListView, &rc);
  311.    hdLayout.prc = &rc;
  312.    hdLayout.pwpos = &wpos;
  313.    Header_Layout(hwndHeader, &hdLayout);
  314.    SetWindowPos(  hwndHeader, 
  315.                   wpos.hwndInsertAfter, 
  316.                   wpos.x, 
  317.                   wpos.y,
  318.                   wpos.cx, 
  319.                   wpos.cy, 
  320.                   wpos.flags | SWP_SHOWWINDOW);
  321.    ListView_EnsureVisible(hwndListView, 0, FALSE);
  322.    }
  323. }
  324. /******************************************************************************
  325.    InitListView
  326. ******************************************************************************/
  327. BOOL InitListView(HWND hwndListView)
  328. {
  329. LV_COLUMN   lvColumn;
  330. int         i;
  331. TCHAR       szString[5][20] = {"Main Column", "Column 1", "Column 2", "Column 3", "Column 4"};
  332. //empty the list
  333. ListView_DeleteAllItems(hwndListView);
  334. //initialize the columns
  335. lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  336. lvColumn.fmt = LVCFMT_LEFT;
  337. lvColumn.cx = 120;
  338. for(i = 0; i < 5; i++)
  339.    {
  340.    lvColumn.pszText = szString[i];
  341.    ListView_InsertColumn(hwndListView, i, &lvColumn);
  342.    }
  343. InsertListViewItems(hwndListView);
  344. return TRUE;
  345. }
  346. /******************************************************************************
  347.    InsertListViewItems
  348. ******************************************************************************/
  349. BOOL InsertListViewItems(HWND hwndListView)
  350. {
  351. //empty the list
  352. ListView_DeleteAllItems(hwndListView);
  353. //set the number of items in the list
  354. ListView_SetItemCount(hwndListView, ITEM_COUNT);
  355. return TRUE;
  356. }
  357. /**************************************************************************
  358.    ListViewNotify()
  359. **************************************************************************/
  360. LRESULT ListViewNotify(HWND hWnd, LPARAM lParam)
  361. {
  362. LPNMHDR  lpnmh = (LPNMHDR) lParam;
  363. HWND     hwndListView = GetDlgItem(hWnd, ID_LISTVIEW);
  364. switch(lpnmh->code)
  365.    {
  366.    case LVN_GETDISPINFO:
  367.       {
  368.       LV_DISPINFO *lpdi = (LV_DISPINFO *)lParam;
  369.       TCHAR szString[MAX_PATH];
  370.       if(lpdi->item.iSubItem)
  371.          {
  372.          if(lpdi->item.mask & LVIF_TEXT)
  373.             {
  374.             wsprintf(szString, "Item %d - Column %d", lpdi->item.iItem + 1, lpdi->item.iSubItem);
  375.             lstrcpy(lpdi->item.pszText, szString);
  376.             }
  377.          }
  378.       else
  379.          {
  380.          if(lpdi->item.mask & LVIF_TEXT)
  381.             {
  382.             wsprintf(szString, "Item %d", lpdi->item.iItem + 1);
  383.             lstrcpy(lpdi->item.pszText, szString);
  384.             }
  385.          if(lpdi->item.mask & LVIF_IMAGE)
  386.             {
  387.             lpdi->item.iImage = 0;
  388.             }
  389.          }
  390.       }
  391.       return 0;
  392.    case LVN_ODCACHEHINT:
  393.       {
  394.       LPNMLVCACHEHINT   lpCacheHint = (LPNMLVCACHEHINT)lParam;
  395.       /*
  396.       This sample doesn't use this notification, but this is sent when the 
  397.       ListView is about to ask for a range of items. On this notification, 
  398.       you should load the specified items into your local cache. It is still 
  399.       possible to get an LVN_GETDISPINFO for an item that has not been cached, 
  400.       therefore, your application must take into account the chance of this 
  401.       occurring.
  402.       */
  403.       }
  404.       return 0;
  405.    case LVN_ODFINDITEM:
  406.       {
  407.       LPNMLVFINDITEM lpFindItem = (LPNMLVFINDITEM)lParam;
  408.       /*
  409.       This sample doesn't use this notification, but this is sent when the 
  410.       ListView needs a particular item. Return -1 if the item is not found.
  411.       */
  412.       }
  413.       return 0;
  414.    }
  415. return 0;
  416. }
  417. /**************************************************************************
  418.    ErrorHandlerEx()
  419. **************************************************************************/
  420. void ErrorHandlerEx( WORD wLine, LPSTR lpszFile )
  421. {
  422. LPVOID lpvMessage;
  423. DWORD  dwError;
  424. char szBuffer[256];
  425. // Allow FormatMessage() to look up the error code returned by GetLastError
  426. dwError = FormatMessage(   FORMAT_MESSAGE_ALLOCATE_BUFFER | 
  427.                               FORMAT_MESSAGE_FROM_SYSTEM, 
  428.                            NULL, 
  429.                            GetLastError(), 
  430.                            MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 
  431.                            (LPTSTR)&lpvMessage, 
  432.                            0, 
  433.                            NULL);
  434. // Check to see if an error occured calling FormatMessage()
  435. if (0 == dwError)
  436.    {
  437.    wsprintf(   szBuffer, 
  438.                "An error occured calling FormatMessage()."
  439.                "Error Code %d", 
  440.                GetLastError());
  441.    MessageBox( NULL, 
  442.                szBuffer, 
  443.                "Generic", 
  444.                MB_ICONSTOP | MB_ICONEXCLAMATION);
  445.    return;
  446.    }
  447. // Display the error infromation along with the place the error happened.
  448. wsprintf(szBuffer, "Generic, Line=%d, File=%s", wLine, lpszFile);
  449. MessageBox(NULL, lpvMessage, szBuffer, MB_ICONEXCLAMATION | MB_OK);
  450. }
  451. /**************************************************************************
  452.    SwitchView()
  453. **************************************************************************/
  454. void SwitchView(HWND hwndListView, DWORD dwView)
  455. {
  456. DWORD dwStyle = GetWindowLong(hwndListView, GWL_STYLE);
  457. SetWindowLong(hwndListView, GWL_STYLE, (dwStyle & ~LVS_TYPEMASK) | dwView);
  458. ResizeListView(hwndListView, GetParent(hwndListView));
  459. }
  460. /**************************************************************************
  461.    DoContextMenu()
  462. **************************************************************************/
  463. BOOL DoContextMenu(  HWND hWnd, 
  464.                      WPARAM wParam, 
  465.                      LPARAM lParam)
  466. {
  467. HWND  hwndListView = (HWND)wParam;
  468. HMENU hMenuLoad,
  469.       hMenu;
  470. if(hwndListView != GetDlgItem(hWnd, ID_LISTVIEW))
  471.    return FALSE;
  472. hMenuLoad = LoadMenu(g_hInst, MAKEINTRESOURCE(IDM_CONTEXT_MENU));
  473. hMenu = GetSubMenu(hMenuLoad, 0);
  474. UpdateMenu(hwndListView, hMenu);
  475. TrackPopupMenu(   hMenu,
  476.                   TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  477.                   LOWORD(lParam),
  478.                   HIWORD(lParam),
  479.                   0,
  480.                   hWnd,
  481.                   NULL);
  482. DestroyMenu(hMenuLoad);
  483. return TRUE;
  484. }
  485. /**************************************************************************
  486.    UpdateMenu()
  487. **************************************************************************/
  488. void UpdateMenu(HWND hwndListView, HMENU hMenu)
  489. {
  490. UINT  uID;
  491. DWORD dwStyle;
  492. //uncheck all of these guys
  493. CheckMenuItem(hMenu, IDM_LARGE_ICONS,  MF_BYCOMMAND | MF_UNCHECKED);
  494. CheckMenuItem(hMenu, IDM_SMALL_ICONS,  MF_BYCOMMAND | MF_UNCHECKED);
  495. CheckMenuItem(hMenu, IDM_LIST,  MF_BYCOMMAND | MF_UNCHECKED);
  496. CheckMenuItem(hMenu, IDM_REPORT,  MF_BYCOMMAND | MF_UNCHECKED);
  497. //check the appropriate view menu item
  498. dwStyle = GetWindowLong(hwndListView, GWL_STYLE);
  499. switch(dwStyle & LVS_TYPEMASK)
  500.    {
  501.    case LVS_ICON:
  502.       uID = IDM_LARGE_ICONS;
  503.       break;
  504.       
  505.    case LVS_SMALLICON:
  506.       uID = IDM_SMALL_ICONS;
  507.       break;
  508.       
  509.    case LVS_LIST:
  510.       uID = IDM_LIST;
  511.       break;
  512.    
  513.    case LVS_REPORT:
  514.       uID = IDM_REPORT;
  515.       break;
  516.    }
  517. CheckMenuRadioItem(hMenu, IDM_LARGE_ICONS, IDM_REPORT, uID,  MF_BYCOMMAND | MF_CHECKED);
  518. }