PROGRESS_CLASS или msctls_progress32

Тема в разделе "WASM.BEGINNERS", создана пользователем Zhelezovsky, 1 дек 2006.

  1. Zhelezovsky

    Zhelezovsky Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    39
    Создавал ProgressBar. Получилось. После того как в пример Iczelion'a посмотрел.
    Вопросы появились следующие:
    1) Почему после

    mov InitCtrls.dwSize, sizeof INITCOMMONCONTROLSEX
    mov InitCtrls.dwICC, ICC_PROGRESS_CLASS
    invoke InitCommonControlsEx, ADDR InitCtrls

    Винда отвечает, что класс уже существует? Я его до этих строк не регистрировал.
    2) Почему пример Microsoft из MSDN

    InitCommonControls();
    hwndPB = CreateWindowEx(0, PROGRESS_CLASS,
    (LPSTR) NULL, WS_CHILD | WS_VISIBLE, Вариант С++
    rcClient.left, rcClient.bottom
    cyVScroll, rcClient.right, cyVScroll,
    hwndParent, (HMENU) 0, g_hinst, NULL);

    pbProgressIndClass db "PROGRESS_CLASS", 0
    invoke InitCommonControls
    invoke CreateWindowEx, NULL, ADDR pbProgressIndClass, NULL,\
    WS_CHILD or WS_VISIBLE,\ Вариант Asm
    8, 160, 425, 17, hWin, NULL, hInstance, NULL
    mov hpbProgressInd, eax

    не работает? А работает только тогда, если PROGRESS_CLASS заменить на msctls_progress32, как у Iczelion'a?
    Получается, что MSDN врёт?
     
  2. AmLupus

    AmLupus New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2006
    Сообщения:
    5
    Под PROGRESS_CLASS прогрммисты из MS понимают какраз имя этого класса(например msctls_progress32).
     
  3. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    #define PROGRESS_CLASSA "msctls_progress32"

    Это GetLastError отвечает? А ты его когда вызываешь, всегда или только если InitCommonControlsEx возвращает 0?
     
  4. Zhelezovsky

    Zhelezovsky Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    39
    Вряд ли. Описание значений поля dwICC:
    dwICC
    Set of bit flags that indicate which common control classes will be loaded from the DLL. This value can be a combination of the following:
    ICC_ANIMATE_CLASS
    Load animate control class.
    ICC_BAR_CLASSES
    Load toolbar, status bar, trackbar, and ToolTip control classes.
    ICC_COOL_CLASSES
    Load rebar control class.
    ICC_DATE_CLASSES
    Load date and time picker control class.
    ICC_HOTKEY_CLASS
    Load hot key control class.
    ICC_INTERNET_CLASSES
    Load IP address class.
    ICC_LINK_CLASS
    Load a hyperlink control class.
    ICC_LISTVIEW_CLASSES
    Load list-view and header control classes.
    ICC_NATIVEFNTCTL_CLASS
    Load a native font control class.
    ICC_PAGESCROLLER_CLASS
    Load pager control class.
    ICC_PROGRESS_CLASS
    Load progress bar control class.
    ICC_STANDARD_CLASSES
    Load one of the intrinsic User32 control classes. The user controls include button, edit, static, listbox, combobox, and scrollbar.
    ICC_TAB_CLASSES
    Load tab and ToolTip control classes.
    ICC_TREEVIEW_CLASSES
    Load tree-view and ToolTip control classes.
    ICC_UPDOWN_CLASS
    Load up-down control class.
    ICC_USEREX_CLASSES
    Load ComboBoxEx class.
    ICC_WIN95_CLASSES
    Load animate control, header, hot key, list-view, progress bar, status bar, tab, ToolTip, toolbar, trackbar, tree-view, and up-down control classes.

    IceStudent
    Вот полный текст программы из MSDN. Здесь нет #define PROGRESS_CLASSA "msctls_progress32".
    Код (Text):
    1. // ParseALargeFile - parses a large file and uses a
    2. // progress bar to indicate the progress of the
    3. // parsing operation.
    4. // Returns TRUE if successful, or FALSE otherwise.
    5. // hwndParent - parent window of the progress bar.
    6. // lpszFileName - name of the file to parse.
    7. //
    8. // Global variable
    9. //     g_hinst - instance handle
    10.  
    11. extern HINSTANCE g_hinst;
    12.  
    13. BOOL ParseALargeFile(HWND hwndParent, LPSTR lpszFileName)
    14. {
    15.     RECT rcClient;  // Client area of parent window
    16.     int cyVScroll;  // Height of scroll bar arrow
    17.     HWND hwndPB;    // Handle of progress bar
    18.     HANDLE hFile;   // Handle of file
    19.     DWORD cb;       // Size of file and count of
    20.                     // bytes read
    21.     LPCH pch;       // Address of data read from
    22.                     // file
    23.     LPCH pchTmp;    // Temporary pointer
    24.  
    25.  
    26.  
    27.     // Ensure that the common control DLL is loaded
    28.     // and create a progress bar along the bottom of
    29.     // the client area of the parent window.
    30.     // Base the height of the progress bar on the
    31.     // height of a scroll bar arrow.
    32.     InitCommonControls();
    33.     GetClientRect(hwndParent, &rcClient);
    34.     cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
    35.     hwndPB = CreateWindowEx(0, PROGRESS_CLASS,
    36.              (LPSTR) NULL, WS_CHILD | WS_VISIBLE,
    37.              rcClient.left, rcClient.bottom
    38.              cyVScroll, rcClient.right, cyVScroll,
    39.              hwndParent, (HMENU) 0, g_hinst, NULL);
    40.  
    41.    // Open the file for reading, and retrieve the
    42.    // size of the file.
    43.  
    44.     hFile = CreateFile(lpszFileName, GENERIC_READ,
    45.             FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)
    46.             NULL, OPEN_EXISTING,
    47.             FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
    48.  
    49.     if (hFile == (HANDLE) INVALID_HANDLE_VALUE)
    50.         return FALSE;
    51.  
    52.     cb = GetFileSize(hFile, (LPDWORD) NULL);
    53.  
    54.     // Set the range and increment of the progress
    55.     // bar.
    56.  
    57.     SendMessage(hwndPB, PBM_SETRANGE, 0,
    58.                 MAKELPARAM(0, cb / 2048));
    59.     SendMessage(hwndPB, PBM_SETSTEP, (WPARAM) 1, 0);
    60.  
    61.     // Parse the file.
    62.     pch = (LPCH) LocalAlloc(LPTR, sizeof(char) *
    63.            2048);
    64.     pchTmp = pch;
    65.     do {
    66.         ReadFile(hFile, pchTmp, sizeof(char) * 2048,
    67.                  &cb,
    68.             (LPOVERLAPPED) NULL);
    69.         // TODO: Write an error handler to check that all the
    70.         // requested data was read.
    71.         .
    72.         .
    73.         // Include here any code that parses the
    74.         // file.
    75.         .
    76.        // Advance the current position of the
    77.        // progress bar by the increment.
    78.        SendMessage(hwndPB, PBM_STEPIT, 0, 0);
    79.       } while (cb);
    80.  
    81.    CloseHandle((HANDLE) hFile);
    82.    DestroyWindow(hwndPB);
    83.    
    84.     return TRUE;
    85. }
    Хотя, может, статья устарела, и её не обновили вовремя.
    Соответствия между названиями классов и контролами нашёл в таблице, описывающей изменения классов в новой Висте.
    А то, что класс уже существует, показывает OllyDbg (ERROR_CLASS_ALREADY_EXISTS (00000582) ). GetLastError я вообще не вызываю. Возвращаемое значение InitCommonControlsEx равно 1(eax=1), если верить отладчику.
     
  5. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Zhelezovsky
    Смешались в кучу кони, люди и залпы тысячи орудий сплелись в кошмарный вой..

    ICC_PROGRESS_CLASS и PROGRESS_CLASS. Найди 10 отличий.

    Зато есть в инклудах. Пробежись по ним и всё увидишь сам.

    А ты не верь всему, что тебе показывают. Вот лучше загляни в справочник (PSDK) и поищи в описании функции InitCommonControlsEx упоминание GetLastError. Нашёл? Я - нет. Но это скорее исключение. Чаще там написано примерно так:
    Теперь перечитай ещё раз и вдумайся. Потом перечитай ещё раз.
     
  6. Zhelezovsky

    Zhelezovsky Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    39
    Ясно. InitCommonControlsEx не влияет на GetLastError.
     
  7. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Точнее, на GetLastError нужно смотреть только если функция вернула ошибку. Это правило.
     
  8. Zhelezovsky

    Zhelezovsky Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    39
    А если в описании функции не сказано, что для получения подробной информации об ошибке надо вызвать GetLastError, то она, в принципе, не должна влиять на это хранилище ошибок?
     
  9. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Zhelezovsky
    не должна влиять на это хранилище ошибок?
    Правильно написанная не должна. Т.е. должна содержать
    Код (Text):
    1. void foo(void)
    2. {
    3.   DWORD dwErr = GetLastError();
    4.   ...
    5.   SetLastError(dwErr);
    6.   return;
    7. }
    Только полагаться на это не надо.
     
  10. Zhelezovsky

    Zhelezovsky Member

    Публикаций:
    0
    Регистрация:
    24 окт 2006
    Сообщения:
    39
    Ок, благодарю за объяснения.