На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Почему ListView не выводится на экран ?
    [attach=#0][/attach][attach=#0][/attach]Добрый вечер!
    Решил соорудить простой пример ListView на WinApi, но, к сожалению, я так и не смог заставить его заработать.
    Видно, что он что-то пытается вывести (см. серую полоску) вверху окна, но это не совсем то, что надо.
    Код прилагается.
    InitInstance создает главное окно, вызывает:
    - CreateListView - для создания окна ListView,
    - InsertListViewItems - для создания элементов ListView.
    Обработчик WM_MOTIFY - в конце текста, он вызывается.
    Не поможете разобраться - что не так, почему ListView нормально не рисуется ?


    Вот код (это вся программа).

    ExpandedWrap disabled
      #pragma comment( lib, "comctl32" )
       
      #include "framework.h"
      #include "commctrl.h"
      #include <windowsx.h>       // HANDLE_MSG
      #include "ProcList.h"
      #include <assert.h>
       
      #define MAX_LOADSTRING 100
       
      // Глобальные переменные:
      HINSTANCE hInst;                                // текущий экземпляр
      WCHAR szTitle[MAX_LOADSTRING];                  // Текст строки заголовка
      WCHAR szWindowClass[MAX_LOADSTRING];            // имя класса главного окна
       
      // Отправить объявления функций, включенных в этот модуль кода:
      ATOM                MyRegisterClass(HINSTANCE hInstance);
      BOOL                InitInstance(HINSTANCE, int);
      LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
      INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
      // --------------------------
      HWND CreateListView(HINSTANCE hInstance, HWND hwndParent);
      BOOL InsertListViewItems(HWND hWndListView, int cItems);
      void HandleWM_NOTIFY(LPARAM lParam);
       
      int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                           _In_opt_ HINSTANCE hPrevInstance,
                           _In_ LPWSTR    lpCmdLine,
                           _In_ int       nCmdShow)
      {
          UNREFERENCED_PARAMETER(hPrevInstance);
          UNREFERENCED_PARAMETER(lpCmdLine);
       
          INITCOMMONCONTROLSEX InitCtrls;
          InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
          InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
          BOOL bRet = InitCommonControlsEx(&InitCtrls);
          assert(bRet == TRUE);
          //InitCommonControls();
       
       
          // Инициализация глобальных строк
          LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
          LoadStringW(hInstance, IDC_PROCLIST, szWindowClass, MAX_LOADSTRING);
          MyRegisterClass(hInstance);
       
          // Выполнить инициализацию приложения:
          if (!InitInstance (hInstance, nCmdShow))
          {
              return FALSE;
          }
       
          HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PROCLIST));
       
          MSG msg;
       
          // Цикл основного сообщения:
          while (GetMessage(&msg, nullptr, 0, 0))
          {
              if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
              {
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
              }
          }
       
          return (int) msg.wParam;
      }
       
       
       
      //
      //  ФУНКЦИЯ: MyRegisterClass()
      //
      //  ЦЕЛЬ: Регистрирует класс окна.
      //
      ATOM MyRegisterClass(HINSTANCE hInstance)
      {
          WNDCLASSEXW wcex;
       
          wcex.cbSize = sizeof(WNDCLASSEX);
       
          wcex.style          = CS_HREDRAW | CS_VREDRAW;
          wcex.lpfnWndProc    = WndProc;
          wcex.cbClsExtra     = 0;
          wcex.cbWndExtra     = 0;
          wcex.hInstance      = hInstance;
          wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROCLIST));
          wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
          wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
          wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_PROCLIST);
          wcex.lpszClassName  = szWindowClass;
          wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
       
          return RegisterClassExW(&wcex);
      }
       
      //
      //   ФУНКЦИЯ: InitInstance(HINSTANCE, int)
      //
      //   ЦЕЛЬ: Сохраняет маркер экземпляра и создает главное окно
      //
      //   КОММЕНТАРИИ:
      //
      //        В этой функции маркер экземпляра сохраняется в глобальной переменной, а также
      //        создается и выводится главное окно программы.
      //
      BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
      {
         hInst = hInstance; // Сохранить маркер экземпляра в глобальной переменной
       
         HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
       
         if (!hWnd)
         {
            return FALSE;
         }
       
         HWND hListView = CreateListView(hInstance, hWnd);
         assert(hListView != 0);
         if (!hListView) {
             BOOL ok = InsertListViewItems(hListView, 5);
         }
       
       
         ShowWindow(hWnd, nCmdShow);
         UpdateWindow(hWnd);
         if (!hListView) {
             ShowWindow(hListView, SW_SHOW);
             UpdateWindow(hListView);
         }
       
         return TRUE;
      }
       
      //
      //  ФУНКЦИЯ: WndProc(HWND, UINT, WPARAM, LPARAM)
      //
      //  ЦЕЛЬ: Обрабатывает сообщения в главном окне.
      //
      //  WM_COMMAND  - обработать меню приложения
      //  WM_PAINT    - Отрисовка главного окна
      //  WM_DESTROY  - отправить сообщение о выходе и вернуться
      //
      //
      LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
      {
          switch (message)
          {
          case WM_COMMAND:
              {
                  int wmId = LOWORD(wParam);
                  // Разобрать выбор в меню:
                  switch (wmId)
                  {
                  case IDM_ABOUT:
                      DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                      break;
                  case IDM_EXIT:
                      DestroyWindow(hWnd);
                      break;
                  default:
                      return DefWindowProc(hWnd, message, wParam, lParam);
                  }
              }
              break;
          case WM_PAINT:
              {
                  PAINTSTRUCT ps;
                  HDC hdc = BeginPaint(hWnd, &ps);
                  // TODO: Добавьте сюда любой код прорисовки, использующий HDC...
                  EndPaint(hWnd, &ps);
              }
              break;
          case WM_DESTROY:
              PostQuitMessage(0);
              break;
          // -----------------------
          case WM_NOTIFY:
       
              HandleWM_NOTIFY(lParam);
              break;
          // -----------------------
          default:
              return DefWindowProc(hWnd, message, wParam, lParam);
          }
          return 0;
      }
       
      // Обработчик сообщений для окна "О программе".
      INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
      {
          UNREFERENCED_PARAMETER(lParam);
          switch (message)
          {
          case WM_INITDIALOG:
              return (INT_PTR)TRUE;
       
          case WM_COMMAND:
              if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
              {
                  EndDialog(hDlg, LOWORD(wParam));
                  return (INT_PTR)TRUE;
              }
              break;
          }
          return (INT_PTR)FALSE;
      }
       
       
       
      // CreateListView: Creates a list-view control in report view.
      // Returns the handle to the new control
      // TO DO:  The calling procedure should determine whether the handle is NULL, in case
      // of an error in creation.
      //
      // HINST hInst: The global handle to the application instance.
      // HWND  hWndParent: The handle to the control's parent window.
      //
      HWND CreateListView(HINSTANCE hInstance, HWND hwndParent)
      {
          INITCOMMONCONTROLSEX icex;           // Structure for control initialization.
          icex.dwICC = ICC_LISTVIEW_CLASSES;
          InitCommonControlsEx(&icex);
       
          RECT rcClient;                       // The parent window's client area.
       
          GetClientRect(hwndParent, &rcClient);
       
          // Create the list-view window in report view with label editing enabled.
          HMENU hMenu = NULL; //  (HMENU)IDM_CODE_SAMPLES
          HWND hWndListView = CreateWindow(WC_LISTVIEW,
              L"",
              WS_CHILD | LVS_REPORT | LVS_EDITLABELS | WS_VISIBLE,
              0, 0,
              rcClient.right - rcClient.left,
              rcClient.bottom - rcClient.top,
              hwndParent,
              hMenu,
              hInstance,
              NULL);
       
          return (hWndListView);
      }
       
       
      // InsertListViewItems: Inserts items into a list view.
      // hWndListView:        Handle to the list-view control.
      // cItems:              Number of items to insert.
      // Returns TRUE if successful, and FALSE otherwise.
      BOOL InsertListViewItems(HWND hWndListView, int cItems)
      {
          LVITEM lvI = { 0 };
       
          // Initialize LVITEM members that are common to all items.
          lvI.pszText = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
          lvI.mask = LVIF_TEXT | /*LVIF_IMAGE | */ LVIF_STATE;
          lvI.stateMask = 0;
          lvI.iSubItem = 0;
          lvI.state = 0;
       
          // Initialize LVITEM members that are different for each item.
          for (int index = 0; index < cItems; index++)
          {
              lvI.iItem = index;
              lvI.iImage = index;
       
              // Insert items into the list.
              int ErrCode = ListView_InsertItem(hWndListView, &lvI);
              assert(ErrCode == 0);
              //return FALSE;
       
              int NewColWidth = LVSCW_AUTOSIZE;
              BOOL ok_set = ListView_SetColumnWidth(hWndListView, index, NewColWidth);
              assert(ok_set == TRUE);
          }
       
          return TRUE;
      }
       
       
      // HandleWM_NOTIFY - Handles the LVN_GETDISPINFO notification code that is
      //         sent in a WM_NOTIFY to the list view parent window. The function
      //        provides display strings for list view items and subitems.
      //
      // lParam - The LPARAM parameter passed with the WM_NOTIFY message.
      // rgPetInfo - A global array of structures, defined as follows:
              struct PETINFO
              {
                  TCHAR szKind[10];
                  TCHAR szBreed[50];
                  TCHAR szPrice[20];
              };
       
              PETINFO rgPetInfo[ ] =
              {
                  {TEXT("Dog"),  TEXT("Poodle"),     TEXT("$300.00")},
                  {TEXT("Cat"),  TEXT("Siamese"),    TEXT("$100.00")},
                  {TEXT("Fish"), TEXT("Angel Fish"), TEXT("$10.00")},
                  {TEXT("Bird"), TEXT("Parakeet"),   TEXT("$5.00")},
                  {TEXT("Toad"), TEXT("Woodhouse"),  TEXT("$0.25")},
              };
       
      void HandleWM_NOTIFY(LPARAM lParam)
      {
          NMLVDISPINFO* plvdi;
       
          switch (((LPNMHDR)lParam)->code)
          {
          case LVN_GETDISPINFO:
       
              plvdi = (NMLVDISPINFO*)lParam;
       
              switch (plvdi->item.iSubItem)
              {
              case 0:
                  plvdi->item.pszText = rgPetInfo[plvdi->item.iItem].szKind;
                  break;
       
              case 1:
                  plvdi->item.pszText = rgPetInfo[plvdi->item.iItem].szBreed;
                  break;
       
              case 2:
                  plvdi->item.pszText = rgPetInfo[plvdi->item.iItem].szPrice;
                  break;
       
              default:
                  break;
              }
       
              break;
       
          }
          // NOTE: In addition to setting pszText to point to the item text, you could
          // copy the item text into pszText using StringCchCopy. For example:
          //
          // StringCchCopy(plvdi->item.pszText,
          //                         plvdi->item.cchTextMax,
          //                         rgPetInfo[plvdi->item.iItem].szKind);
       
          return;
      }
      Цитата Lun2 @
      Не поможете разобраться - что не так, почему ListView нормально не рисуется ?

      А вот это - зачем ?
      ExpandedWrap disabled
        if (!hListView) {

      (в функции InitInstance)
      Сообщение отредактировано: ЫукпШ -
        А кто будет добавлять столбцы перед добавлением строк?

        ExpandedWrap disabled
              LVCOLUMN lvColumn = { 0 };
              lvColumn.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
           
              lvColumn.pszText = const_cast<LPWSTR>(L"Column 1");
              lvColumn.cx = 200; // Width of the column
              ListView_InsertColumn(hWndListView, 0, &lvColumn);
           
              LVITEM lvI = { 0 };
           
              // Initialize LVITEM members that are common to all items.
              lvI.pszText = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
              lvI.mask = LVIF_TEXT | /*LVIF_IMAGE | */ LVIF_STATE;
              lvI.stateMask = 0;
              lvI.iSubItem = 0;
              lvI.state = 0;


        А это зачем?
        Почему не вернуть 0 в случае завершения программы?

        ExpandedWrap disabled
          return (int) msg.wParam;


        Инициализацию InitCommonControlsEx нужно делать всего один раз.
        Причем во второй инициализации вы не задали размер структуры
        ExpandedWrap disabled
          InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);


        Добавляем только если не удалось создать окно?????
        ExpandedWrap disabled
             if (!hListView) {
                 BOOL ok = InsertListViewItems(hListView, 5);
             }

        P.S. На кой вам писать оконный интерфейс на чистом WinAPI? :) Это же мазохизм чистой воды.
        Ну посмотрите хотя бы в сторону MFC. Про остальные фреймворки я уж не говорю.
        Сообщение отредактировано: sharky72 -
          Цитата sharky72 @
          А кто будет добавлять столбцы перед добавлением строк?



          sharky72, спасибо!
          Вы правы - надо было добавить столбцы!

          Цитата sharky72 @
          P.S. На кой вам писать оконный интерфейс на чистом WinAPI? :) Это же мазохизм чистой воды.
          Ну посмотрите хотя бы в сторону MFC. Про остальные фреймворки я уж не говорю.


          Предыдущие мои разборки (с другими диалогами) были как раз с MFC.
          Не сказать, чтоб слишком просто и быстро :(
          В этой задаче мне нужен только ListView, а не богатый интерфейс в целом (ну может пара кнопок еще).
          Я посчитал, что изучение MFC и одного Listview winapi не больно-то и отличаются по времени.
            Цитата Lun2 @
            В этой задаче мне нужен только ListView, а не богатый интерфейс в целом (ну может пара кнопок еще).
            Я посчитал, что изучение MFC и одного Listview winapi не больно-то и отличаются по времени.

            Ну и зря. Количество кода которого надо набить руками в WinAPI и MFC различается порядками. Плюс стоит вам чуть выйти за пределы "академических" экзерцисов, в сторону хоть какого то вменяемого UI который бы работал на современном железе и поддерживал современные системы и те же HiDPI мониторы - мое вам сочувствие. Забудьте. Так же как писать под винду на асме. Можно, но пахнет редкими извращениями.
            Сообщение отредактировано: sharky72 -
            1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,6006 ]   [ 15 queries used ]   [ Generated: 2.02.26, 00:13 GMT ]