Главная страница
Навигация по странице:

  • 3. ЭЛЕМЕНТЫ УПРАВЛЕНИЯ ОБЩЕГО ПОЛЬЗОВАНИЯ

  • Win32 api программирование


    Скачать 0.78 Mb.
    НазваниеWin32 api программирование
    Дата02.02.2018
    Размер0.78 Mb.
    Формат файлаpdf
    Имя файлаitmo426.pdf
    ТипУчебное пособие
    #35685
    страница5 из 8
    1   2   3   4   5   6   7   8
    2.3. Приложение с главным окном и меню
    /*
    Файл resource.h
    */
    //
    //{{NO_DEPENDENCIES}}
    // Microsoft Visual C++ generated include file.
    // Used by 1111.rc

    47
    //
    #define IDD_DIALOGBAR 103
    #define IDC_BUTTON1 1002
    #define IDC_STATIC_1 1003
    // Next default values for new objects
    //
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE 101
    #define _APS_NEXT_COMMAND_VALUE 40001
    #define _APS_NEXT_CONTROL_VALUE 1004
    #define _APS_NEXT_SYMED_VALUE 101
    #endif
    #endif
    Если открыть файл описания ресурсов 1111.rc в текстовом режи- ме, то можно увидеть следующее определение шаблона диалогового окна:
    ////////////
    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    //...
    ///////////////////////////////////////////////////////////
    //
    // Dialog
    //
    IDD_DIALOGBAR DIALOGEX 0, 0, 153, 62
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION |
    WS_SYSMENU
    CAPTION "СПб ГУ ИТМО"
    FONT 10, "Lucida Console", 700, 0, 0xCC
    BEGIN
    PUSHBUTTON "Ok",IDOK,105,42,41,14,BS_CENTER
    CTEXT "ЛИТМО\n КАФЕДРА ПКС\n2009",
    IDC_STATIC,44,14,63,26,WS_TABSTOP
    END
    ///////////////////////////////////////////////////////////
    /*
    Файл 1111.cpp
    */
    /*Операторы препроцессора*/
    /*
    #define UNICODE
    #ifdef UNICODE
    #define _UNICODE
    #endif
    */
    #define STRICT
    #include
    #include
    /*
    Файл tchar.h состоит из макросов, которые ссылаются на UNICODE данные и функции, если определен макрос UNICODE, и на ANSI данные и функции, если этот макрос не определен, кроме того он полностью заменяет файл string.h
    */
    #include

    48
    #include "resource.h"
    /*
    Идентификаторы пунктов меню приведены для наглядности, лучше всего их повестить в файл resource.h
    */
    #define ID_FILE_TEST 40001
    #define ID_FILE_EXIT 40002
    #define ID_HELP_ABOUT 40003
    /*Прототип оконной функции*/
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    /*Прототип функции модального диалога*/
    INT_PTR CALLBACK AboutProc(HWND, UINT, WPARAM, LPARAM);
    /*
    Прототип функция обратного вызова обработки сообщений от таймера
    */
    VOID CALLBACK TimerProc(HWND,UINT,UINT_PTR,DWORD);
    /*
    Прототип функции получения текущего времени и преобразование его в символы
    */ void OutTimeDate(HWND);
    /*Дескрипторы всплывающих меню и дескриптор главного меню*/
    HMENU hFileMenu,hHelpMenu,hMenu;
    /*Будет создан логический шрифт*/
    HFONT hFont,hOldFont;
    /*Массив для формирования строки - текущие дата и время*/
    TCHAR szCurrentTime[40]; int nTime=5;//Однократный интервал 5с int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,int nCmdShow)
    {
    /*Произвольный заголовок окна*/
    TCHAR szTitle[]=_TEXT("ИТМО");
    /*Произвольное имя класса*/
    TCHAR szWindowClass[]=_TEXT("QWERTY");
    /*
    Структурная переменная msg типа MSG для получения сообщений
    */
    MSG msg;
    /*
    Структурная переменная wcex типа WNDCLASSEX для задания характеристик окна
    */
    WNDCLASSEX wcex;
    HWND hWnd; //Дескриптор главного окна
    /*Проверяем, было ли это проложение запущено ранее*/ if(hWnd=FindWindow(szWindowClass,NULL))
    {
    /*Проверяем, было ли это окно свернуто в пиктограмму*/ if(IsIconic(hWnd))
    ShowWindow(hWnd,SW_RESTORE);
    /*Выдвигаем окно приложения на передний план*/
    SetForegroundWindow(hWnd); return
    FALSE;

    49
    }
    /*Обнуление всех членов структуры wcex*/ memset(&wcex,0,sizeof(WNDCLASSEX));
    /*Регистрируем класс главного окна*/ wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW;
    /*Определяем оконную процедуру для главного окна*/ wcex.lpfnWndProc =
    (WNDPROC)WndProc;
    //wcex.cbClsExtra
    =
    0;
    //wcex.cbWndExtra
    =
    0; wcex.hInstance
    = hInstance;//Дескриптор приложения
    /*
    Стандартная пиктограмма, которую можно загрузить функцией
    LoadImage()
    */ wcex.hIcon = (HICON)LoadImage(hInstance,
    IDI_APPLICATION,
    IMAGE_ICON,32,32,0);
    /*Стандартный курсор мыши*/ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    /*
    Кисть фона и ее цвет можно определить выражениями: wcex.hbrBackground=(HBRUSH)(COLOR_APPWORKSPACE+1); wcex.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH); или с помощью макроса GetStockBrush(), в этом случае необходимо подключить файл windowsx.h
    */ wcex.hbrBackground=GetStockBrush(LTGRAY_BRUSH);
    //wcex.lpszMenuName
    =
    MAKEINTRESOURCE(IDC_MSG_1);
    /*Имя класса главного окна*/ wcex.lpszClassName
    = szWindowClass; wcex.hIconSm = NULL; if(!RegisterClassEx(&wcex)) return
    FALSE;
    /*Создаем главное окно и делаем его видимым*/ hWnd = CreateWindowEx(WS_EX_WINDOWEDGE,szWindowClass, szTitle,
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,0,CW_USEDEFAULT,0,
    NULL, NULL, hInstance, NULL); if
    (!hWnd) return
    FALSE;
    /*
    Исследуем адресное пространство приложения. Выведем содержимое сегментных регистров команд, данных и стека, а также смещение главной функции и строки с именем класса
    */
    TCHAR szAsm[80];
    USHORT regCS,regDS,regES,regSS;
    __asm{ mov regCS,CS mov regDS,DS mov regES,ES mov regSS,SS
    } wsprintf((LPTSTR)szAsm,_T("CS=%X,DS=%X\nES=%X,SS=%X\n
    WinMain=%X\nszWindowClass=%X"), regCS,regDS,regES,regSS);

    50
    MessageBox(NULL,(LPCTSTR)szAsm,_T("Регистры"),
    MB_ICONINFORMATION);
    /*
    Создаем пустое всплывающее меню самого низкого уровня hFileMenu=CreatePopupMenu()и добавляем в него конечный элемент "Test"
    */
    AppendMenu((hFileMenu=CreatePopupMenu()),
    MF_ENABLED | MFT_STRING,
    ID_FILE_TEST,_TEXT("&Test"));
    /*
    Добавляем в созданное меню конечный элемент "Exit"
    */
    AppendMenu(hFileMenu,MF_GRAYED | MFT_STRING,
    ID_FILE_EXIT,_TEXT("&Exit"));
    /*
    Создаем пустое всплывающее меню самого низкого уровня hHelpMenu=CreatePopupMenu()и добавляем в него конечный элемент "About"
    */
    AppendMenu((hHelpMenu=CreatePopupMenu()),
    MF_ENABLED|MFT_STRING,
    ID_HELP_ABOUT,_TEXT("&About"));
    /*
    Создаем меню верхнего уровня - главное меню hMenu=CreateMenu()и присоединяем созданное подменю"File" к главному меню"
    */
    AppendMenu((hMenu=CreateMenu()),
    MF_ENABLED | MF_POPUP,
    (UINT_PTR)hFileMenu, _TEXT("&File"));
    /*
    Присоединяем созданное подменю "Help" к главному
    Меню
    */
    AppendMenu(hMenu,MF_ENABLED|MF_POPUP,
    (UINT_PTR)hHelpMenu,_TEXT("&Help"));
    /
    *Добавляем в конец главного меню конечный пункт "QUIT"
    */
    AppendMenu(hMenu,MF_GRAYED,(UINT_PTR)11,
    _TEXT("Quit"));
    /*Присоединяем созданное меню к окну приложения*/
    SetMenu(hWnd,hMenu);
    /*Делаем окно видимым на экране*/
    ShowWindow(hWnd, SW_SHOWNORMAL);
    /*
    Функция UpdateWindow() вызывает передачу сообщения WM_PAINT непосредственно оконной процедуре, а функция InvalidateRect() вызывает постановку сообщения WM_PAINT в очередь приложения, а там оно обрабатывается с самым низким приоритетом
    */
    UpdateWindow(hWnd);
    /*Отображаем меню*/
    DrawMenuBar(hWnd);
    /*Цикл обработки сообщений*/ while (GetMessage(&msg, NULL, 0, 0))
    {

    51
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    /*Код возврата*/ return
    (int)msg.wParam;
    }
    /*Оконная функция главного окна*/
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
    WPARAM wParam, LPARAM lParam)
    {
    /*Горизонтальный размер главного окна*/ int xSize=500;
    /*Верикальный размер главного окна*/ int ySize=300;
    /* PAINTSTRUCT - структура с характеристиками рабочей области (заполняется функцией BeginPaint)
    */
    PAINTSTRUCT ps;
    /*
    TEXTMETRIC - структура для получения характеристик шрифта
    */
    TEXTMETRIC tm;
    /*
    LOGFONT - структура для для создания логических шрифтов
    */
    LOGFONT lf;
    /*
    RECT–структура,определящая прямоугольник
    */
    RECT rect;
    LPMINMAXINFO lpmmi;
    Static HFONT hFont,hOldFont;
    /*Дескриптор контекста устройства*/
    HDC hDc;
    /*
    Ширина width и высота height клиентской области окна в пикселях
    */
    UINT width, height;
    /*Имя для шрифта*/
    LPTSTR lpszFace=_TEXT("Times New Roman Cur"); switch (message)
    {
    /*Переход по значению кода сообщения(msg)*/ case WM_CREATE:
    /*Только здесь можно произвести модификацию
    Класса окна. Например,
    SetClassLong(hWnd,GCL_HBRBACKGROUND,
    (LONG)CreateSolidBrush(RGB(200,160,255));
    Значение дескриптора экземпляра приложения определяется,вызовом одной из следующих функций: hInst=GetModuleHandle(NULL); hInst=(HINSTANCE)GetClassLong(hWnd,GCL_HMODULE);
    */
    /*Обнуление всех членов структуры lf*/ memset(&lf,0,sizeof(lf));

    52
    /*Устанавливаем размер шрифта*/ lf.lfHeight=30;
    /*Копируем в структуру имя шрифта*/ lstrcpy(lf.lfFaceName,lpszFace);
    /*Создаем шрифт*/ hFont=CreateFontIndirect(&lf);
    /*Первый немедленный вывод текущего времени*/
    OutTimeDate(hWnd);
    /*
    Функция SetTimer создает системный таймер с периодом 1с
    */
    SetTimer(hWnd,1,1000,(TIMERPROC)NULL); return
    TRUE; case
    WM_TIMER:
    /*
    Функция OutTimeDate запрашивает у системы текущие значения даты и времени, а затем организует их обработку в главном окне приложения.
    */
    OutTimeDate(hWnd); break; case
    WM_KEYDOWN:
    /*Обрабатываем сообщение-нажатие клавиши.*/ switch(wParam)
    { case
    VK_ESCAPE:
    /*
    Посылаем сообщение WM_CLOSE окну (hWnd), после того, как оконная процедура обработает это сооб- щение, система передаст управление инструкции следующей за SendMessage
    */
    SendMessage(hWnd,WM_CLOSE,0,0); break;
    } break; case
    WM_COMMAND: switch(LOWORD(wParam))
    //switch(wParam)
    { case ID_FILE_TEST:
    /*
    Изменяем статус пункта меню ID_FILE_EXIT
    */
    EnableMenuItem(hFileMenu,ID_FILE_EXIT,
    MF_BYCOMMAND|MF_ENABLED);
    /*Ставим отметку (галочка) на пункте меню
    ID_FILE_TEST*/
    CheckMenuItem(hFileMenu,ID_FILE_TEST,
    MF_BYCOMMAND|MF_CHECKED);
    /*Изменяем статус пункта главного меню "QUIT"*/
    EnableMenuItem(GetMenu(hWnd),
    (UINT_PTR)11,MF_BYCOMMAND|MF_ENABLED);
    /*
    Так как изменился статус пункта главного меню, вызываем функцию DrawMenuBar для повторного отображения изменившейся полосы меню
    */
    DrawMenuBar(hWnd);

    53
    /*Устанавливаем таймер на nTime секунд*/
    SetTimer(hWnd,2,nTime*1000,
    (TIMERPROC)TimerProc); break; case ID_FILE_EXIT:
    /*
    Без запроса на закрытие окна - функция
    PostQuitMessage посылает сообщение WM_QUIT
    */
    PostQuitMessage(0);
    /*
    С запросом на закрытие, т.е. окно еще не разруше- но SendMessage(hWnd,WM_CLOSE,0,0);
    */ break; case
    ID_HELP_ABOUT:
    /*
    Функция DialogBox создает и выводит на экран мо- дальное диалоговое окно по шаблону IDD_ABOUTBOX, и не возвращает управление в WndProc пока окно диало- ка не бедет закрыто.
    */
    DialogBox(GetModuleHandle()NULL,
    MAKEINTRESOURCE(IDD_DIALOGBAR), hWnd, (DLGPROC)AboutProc); break; case (UINT)11:
    /*
    Без запроса на закрытие окна - функция
    PostQuitMessage посылает сообщение WM_QUIT
    */
    PostQuitMessage(0); break;
    } break; case
    WM_PAINT:
    /*Получаем контекст устройства*/ hDc
    =
    BeginPaint(hWnd,
    &ps);
    /*Определяем размеры клиентской области окна*/
    GetClientRect(hWnd,&rect);
    /*Выбираем в контест созданный шрифт*/ hOldFont=SelectFont(hDc,hFont);
    /*Получим метрики текста(если это необходимо)*/
    GetTextMetrics(hDc,&tm);
    /*
    Функция SetBkMode устанавливает текущий режим фона.
    TRANSPARENT - в этом режиме вывода текста цвет фона гра- фического элемента игнорируется, т.е. символ выводится на существующем фоне
    */
    SetBkMode(hDc,TRANSPARENT);
    /*
    Функция SetTextColor устанавливает цвет текста для кон- текста устройства, по умолчанию применяется черный цвет.
    Цвет текста синий!
    */
    SetTextColor(hDc,RGB(0,0,128));
    DrawText(hDc,szCurrentTime,-1,&rect,
    DT_SINGLELINE|DT_CENTER|DT_VCENTER);
    /*Освобождаем контекст устройства*/

    54
    EndPaint(hWnd, &ps); break; case
    WM_CLOSE:
    /*
    Сообщение WM_CLOSE появляется при щелчке на кнопке закрытия окна - здесь предназначено для вывода преду- преждающего сообщения
    */ if(MessageBox(hWnd,_T("Вы уверены?"),
    _T("Предупреждение!"),
    MB_YESNO | MB_ICONQUESTION)==IDYES)
    {
    /*
    Функция DestroyWindow разрушает указанное в ее па- раметре окно, т.е. она посылает окну сообщение
    WM_DESTROY. Затем вызывается функция
    PostQuitMessage, которая посылает сообщение WM_QUIT
    */
    DestroyWindow(hWnd);
    } break; case
    WM_SIZE:
    /*
    Ширина width и высота height клиентской области окна в пикселях
    */ width=LOWORD(lParam); height=HIWORD(lParam);
    //... break; case
    WM_LBUTTONDOWN:
    /*Нажата клавиша Shift ?*/ if(wParam & MK_SHIFT)
    {
    MessageBox(hWnd,_T("Нажата клавиша\nShift"),
    _T("Bad boys"),
    MB_OK|MB_ICONEXCLAMATION);
    } break; case
    WM_GETMINMAXINFO: lpmmi=(LPMINMAXINFO)lParam;
    /*
    Минимальный и максимальный размеры окна совпадают
    */ lpmmi->ptMinTrackSize.x=xSize; lpmmi->ptMinTrackSize.y=ySize; lpmmi->ptMaxTrackSize.x=xSize; lpmmi->ptMaxTrackSize.y=ySize; break; case
    WM_DESTROY:
    /*
    Функция DeleteObject удаляет логический объект. К удаляе- мым объектам относятся перья, растровые изображения, кис- ти, области, палитры и шрифты
    */
    /*Удаляем созданный шрифт*/
    DeleteObject(hFont);
    /*Функция KillTimer удаляет таймер*/

    55
    KillTimer(hWnd,1);
    /*
    PostQuitMessage() выполняет только одно действие - ставит в очередь сообщение WM_QUIT. Параметр у этой функции - код возврата, который помещается в wParam
    */
    PostQuitMessage(0); break; default:
    /*Обработка прочих сообщений по умолчанию*/ return
    DefWindowProc(hWnd, message, wParam, lParam);
    } return
    0L;
    }
    /*Оконная функция диалогового окна*/
    INT_PTR CALLBACK AboutProc(HWND hDlg, UINT message,
    WPARAM wParam, LPARAM lParam)
    { switch
    (message)
    { case
    WM_INITDIALOG:
    /*
    Для обрабатываемых сообщений процедура всегда возвращает TRUE
    */ return (INT_PTR)TRUE; case
    WM_COMMAND: if(LOWORD(wParam)==IDOK || LOWORD(wParam)==
    IDCANCEL)
    {
    EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE;
    } break;
    }
    /*
    Для не обрабатываемых сообщений процедура всегда возвращает FALSE
    */ return (INT_PTR)FALSE;
    }
    /*
    Фунуция получения текущего времени и преобразование его в символы
    */ void OutTimeDate(HWND hWnd)
    {
    LPTSTR szDay[]={_T("Вск."),_T("Пнд."),_T("Втр."),
    _T("Ср."),_T("Чтв."),
    _T("Птн."),_T("Суб.")
    };
    LPTSTR szMonth[]={_T(""),_T("Янв."),_T("Февр."),
    _T("Март"),_T("Апр."),
    _T("Май"),_T("Июнь"),
    _T("Июль"),_T("Авг."),

    56
    _T("Сент."),_T("Окт."),
    _T("Нояб."),_T("Дек.")
    };
    TCHAR szT[20];
    SYSTEMTIME SystemTime;
    /*
    Функция GetLocalTime осуществляет выборку местного време- ни, на которое настроен компьютер, т.е. функция заполняет структуру типа SYSTEMTIME в числовом виде.
    */
    GetLocalTime(&SystemTime);
    /*День недели*/ lstrcpy(szCurrentTime, szDay[SystemTime.wDayOfWeek]);
    /*Разделяющий пробел*/ lstrcat((LPTSTR)szCurrentTime,_T(" "));
    /*Месяц*/ lstrcat((LPTSTR)szCurrentTime, szMonth[SystemTime.wMonth]);
    /*Разделяющий пробел*/ lstrcat((LPTSTR)szCurrentTime,_T("
    "));
    /*Дату переводим в символы*/ wsprintf((LPTSTR)szT,_T("%d"),
    SystemTime.wDay); lstrcat((LPTSTR)szCurrentTime,(LPTSTR)szT);
    /*Разделяющий пробел*/ lstrcat((LPTSTR)szCurrentTime,_T("
    "));
    /*Год переводим в символы*/ wsprintf((LPTSTR)szT,_T("%d"),
    SystemTime.wYear); lstrcat((LPTSTR)szCurrentTime,(LPTSTR)szT); lstrcat((LPTSTR)szCurrentTime,_T("---"));
    /*Часы переводим в символы*/ wsprintf((LPTSTR)szT,_T("%d"),
    SystemTime.wHour); lstrcat((LPTSTR)szCurrentTime,(LPTSTR)szT);
    /*Разделяющее двоеточие*/ lstrcat((LPTSTR)szCurrentTime,_T(":"));
    /*Минуты переводим в символы*/ wsprintf((LPTSTR)szT,_T("%d"),
    SystemTime.wMinute); lstrcat((LPTSTR)szCurrentTime,(LPTSTR)szT);
    /*Разделяющее двоеточие*/ lstrcat((LPTSTR)szCurrentTime,_T(":"));
    /*Секунды переводим в символы*/ wsprintf((LPTSTR)szT,_T("%d"),
    SystemTime.wSecond); lstrcat((LPTSTR)szCurrentTime,(LPTSTR)szT);
    /*Перерисовка окна*/
    InvalidateRect(hWnd,NULL,TRUE);
    }
    /*Функция обратного вызова обработки сообщений от таймера*/
    VOID CALLBACK TimerProc(HWND hWnd,UINT uMsg,
    UINT_PTR idEvent,DWORD dwTime)
    {
    TCHAR szTimer[100];
    KillTimer(hWnd,2); wsprintf(szTimer,
    _T("С момента выбора\nпункта меню Test\nпрошло %d c!"),

    57
    nTime);
    MessageBox(NULL,(LPCTSTR)szTimer,
    _T("Предупреждение"),MB_ICONHAND);
    }
    Результат работы программы приведен на рис. 3.
    Рис. 3. Окно приложения с главным меню
    3. ЭЛЕМЕНТЫ УПРАВЛЕНИЯ ОБЩЕГО ПОЛЬЗОВАНИЯ
    Рассмотрим элементы управления главного окна:
    • Toolbar (панель инструментов) – состоит из кнопок быстрого дос- тупа;
    • Statusbar (строка состояния) – информационная строка, которая размещается в нижней части окна приложения.
    Большинство элементов управления общего пользования реализо- вано в виде окна соответствующего предопределенного класса и управ- ляются специфичными для данного класса сообщениями. Элементы управления посылают уведомляющие сообщения родительскому окну, информируя его о происходящих событиях.
    Чтобы использовать в приложении элементы управления общего пользования, необходимо вначале вызвать функцию

    58
    InitCommonControlsEx(), которая регистрирует оконные классы элементов управления. Описание функции находится в файле commctrl.h. Поэтому необходимо в начало исходного файла включить следующую директиву:
    #include
    Кроме того, следует указать компоновщику расположение библио- течного файла comctl32.lib. Функция имеет прототип:
    BOOL InitCommonControlsEx(
    LPINITCOMMONCONTROLSEX lpInitCtrls);
    Параметр lpInitCtrls – адрес структурной переменной типа
    INITCOMMONCONTROLSEX, которая содержит информацию о том, какие классы элементов управления должны быть зарегистрированы. Структура имеет вид: typedef struct tagINITCOMMONCONTROLSEX {
    DWORD dwSize; //размер структуры в байтах
    DWORD dwICC; //флаги загрузки классов из DLL
    } INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
    Второй параметр dwICC структуры может содержать один или не- сколько следующих флагов (полный список флагов в MSDN):
    • ICC_BAR_CLASSES – toolbar, status bar, slider, tooltip;
    • ICC_PROGRESS_CLASS – progress bar;
    • ICC_TREEVIEW_CLASSES – tree view.
    Создание органов управления Toolbar и Statusbar выполняет- ся приложением при обработке функцией главного окна сообщения
    WM_CREATE.
    1   2   3   4   5   6   7   8


    написать администратору сайта