Отправляет email-рассылки с помощью сервиса Sendsay

Статьи по Visual C++

  Все выпуски  

Меню и акселераторы


Информационный Канал Subscribe.Ru

Visual C++
Лучшие статьи с сайта www.p-lib.pp.ru
  Главная | Новости | Статьи | Каталог | Софт | Регистрация | Поиск

Приглашаем авторов статей к сотрудничеству с сайтом. Для того чтобы разместить на сайте статью надо заполнить форму или связаться с нами по E-Mail

NEW!  Все желающие могут предложить свои темы для следующих рассылок. Для этого свяжитесь со мной по E-Mail. Каждое предложение будет рассмотрено.

Новые статьи на сайте

1. ?Липкие? диалоговые окна
Небольшая реализация ?липких? диалоговых окон, как в проигрывателе Winamp.

2. ODBC API
В статье описана работа с СУБД через ODBC API. Как соединиться и считать данные из базы.

3. Подключение и отключение от интернета
Часто возникает проблема создать собственно само подключение, то есть начать дозвон, используя информацию, находящуюся в свойствах ?точки входа?. Решением этой проблемы служат функции RasDial и RasDialDlg.

4. Сериализация в MFC
В статье очень подробно рассматривается механизм сериализации, реализованный в MFC. Автор дает полную информацию о работе макросов DECLARE IMPLEMENT_DYNAMIC, DECLARE/IMPLEMENT_SERIAL и DECLARE/IMPLEMENT_DYNCREATE. Также обсуждается поддержка версий схем сериализации.

5. Метод с возвращаемым значением
Как же нам сделать так, что бы некоторый метод возвращал значение (при вызове этого метода в клиенте, разумеется)? Очень просто...

6. Критические секции
Понятие критической секции позволяет уберечь определенные области программы так, чтобы в этой области программы в данный момент времени исполнялся бы только один поток.

7. Изменение настроек подключения
В этой вы ознакомитесь с функциями, предоставляющими программе создавать и изменять соединения, без применения диалогов и если потребуется без участия пользователя.

8. События
Событие является объектом, очень похожим на семафор, но в несколько видоизмененном виде. Рассмотрим функции для работы с событиями.

9. Internet API. Как и где его использовать
Эта статья обсуждает общие положения работы с Internet application programming interface (API), а затем подробнее рассматривает некоторые из функций...

10. Определение разрыва TCP-соединения
В статье рассматривается один из способов контроля над работоспособностью TCP/IP-соединения под Windows ? создание keep-alive таймера.

Свежие компьютерные новости

12.01.2006 Google откроет книжный интернет-магазин

12.01.2006 Opera Software выпускает браузер для бытовой техники

12.01.2006 Windows ХР загрузили на процессоре с частотой 25 МГц и 18 Мб ОЗУ

12.01.2006 Билл Гейтс не считает Google основным конкурентом

12.01.2006 "Битрикс" и NetPromoter проводят семинар

12.01.2006 Крошечный блок питания PicoPSU-120

12.01.2006 Macworld 2006: Microsoft продолжит выпуск Office для Mac OS

12.01.2006 AOL купила компанию видеопоиска Truveo

Меню и акселераторы

В этой статье я вас ознакомлю с классом CMenu. С помощью этого класса можно создавать меню в MFC приложениях. Так же будет рассмотрен вопрос об использовании акселераторов. Итак, начнем с описания класса CMenu.

Класс CMenu

Рассмотрим некоторые наиболее важные функции и переменные этого класса.

  • m_hMenu ? дескриптор меню, связанный с объектом класса CMenu.
  • BOOL CreateMenu() ? создает пустое меню и связывает его с объектом класса CMenu.
  • BOOL CreatePopupMenu() ? создает пустое выпадающее меню и соединяет с объектом класса CMenu.
  • BOOL LoadMenu(UINT nIDResource) ? загружает меню из ресурсов и соединяет его с объектом класса CMenu. Меню может быть создано программным путем метода заполнения структур MENUITEMTEMPLATEHEADER и MENUITEMTEMPLATE и посредством вызова метода LoadMenuIndirect(const MUNUTEMPLATE *lpMenuTemplate).
  • BOOL Attach(HMENU hMenu) ? пристыковка существующего меню к объекту класса CMenu. Если известен дескриптор меню, то можно определить указатель на соответствующий ему объект CMenu с помощью следующего метода static CMenu* PASCAL FromHandle(HMENU hMenu).
  • BOOL DestroyMenu() ? разрушает объект CMenu и освобождает все ресурсы. Этот метод обычно не вызывается явно, так как он автоматически вызывается из деструктора.
  • BOOL DeleteMenu(UINT uPosition, UINT uFlags) ? метод удаляет указанный элемент меню. uPosition ? определяет удаляемый элемент меню. uFlags ? определяет, как интерпретируется первый параметр. Если флаг равен MF_BYCOMMAND, то первый параметр интерпретируется как идентификатор пункта меню. Если параметр равен MF_BYPOSITION, то первый параметр определяет позицию элемента меню. Первый элемент имеет позицию ноль.
  • BOOL TrackPopupMenu ( UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRact = 0 ) ? метод осуществляет отображение всплывающего (контекстного) меню. Всплывающее меню может быть отображено в любом месте экрана. Метод автоматически отслеживает выбор пункта меню. nFlags ? может быть задан следующими константами: TPM_CENTERALIGN, TMP_LEFTALIGN, TMP_RIGHTALIGN ? для указания позиции выравнивания по горизонтали относительно координаты x, TMP_LEFTBUTTON, TMP_RIGHTBUTTON ? для определения кнопки мыши, выполняющей выбор пункта меню. Координаты x, y ? позиция меню. pWnd ? указатель на окно, в котором находится это меню. Параметр lpRect ? определяет прямоугольную область, в которой щелчок мыши не вызывает исчезновение меню. Если значение параметра NULL, то область ограничена окном меню.
  • BOOL AppenedMenu(UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) и BOOL AppenedMenu(UINT nFlags, UINT_PTR nIDNewItem, const CBitmap* pBmp) Используются для добавления элемента в конец меню. Параметр nFlags может быть комбинацией следующих констант: MF_CHECKED ? переключаемый элемент, состояние ?включен? (отмечается галочкой). MF_UNCHECKED ? переключаемый элемент, состояние ?выключен? (галочки нет). MF_DISABLED ? элемент не лоступен. MF_ENABLED ? элемент доступен. MF_GRAYED ? 2серый? элемент (блокирован). MF_MENUBARBREAK ? элемент линейки меню. MF_OWNERDRAW ? самоотображаемый элемент., меня само отвечает за отображение элемента. MF_POPUP ? элемент меню имеет подменю. MF_SEPARATOR ? отображение горизонтальной разделительной линии. MF_STRING ? элемент является текстовой строкой. Параметр nIDNewItem ? в зависимости от первого параметра отпеделяет либо идентификаторор нового элемента, либо указатель (HMENU) подменю; игнорируется для значения MF_SEPARATOR. Параметр lpszNewItem определяет содержимое нового элемента. Параметр pBmp ? определяет указатель на объект класса CBitmap, который может использоваться в качестве содержимого строки меню. При этом первый параметр не может принимать значения MF_OWNERDRAW и MF_STRING.
  • BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL) и BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, const CBitmap* pBmp) ? поставляют новый элемент в позицию, определяемцю параметром nPosition.
  • UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck) ? устанавливает или сбрасывает галочку у элемента меню. Второй параметр может принимать два значения: MF_CHECKED и MF_UNCHECKED в комбинации с параметрами MF_BYCOMMAND и MF_BYPOSITION.
  • UINT EnableMenuItem(UINT nIDEnableItem, UINT nEnable) ? метод устанавливает для указанного элемента одно из следующих значений: MF_DISABLES и MF_ENABLED, MF_GRAYED.
  • UINT GetMenuItemCount() ? возвращает количество элементов меню.
  • UINT GetMenuItemID(int nPos) ? метод возвращает идентификатор указанного элемента меню.
  • Int GetMenuString(UINT nIDItem, lptstr lpString, int nMaxCount, UINT nFlags) и int GetMenuString(UINT nIDItem, CString& rString, UINT nFlags) ? определяют надпись на указанном элементе меню.
  • BOOL RemoveMenu(UINT nPosition, UINT nFlags) ? метод удаляет указанный элемент меню.
  • UINT GetMenustate(UINT nID, UINT nFlags) ? определяет состояние элемента или число элементов в раскрывающемся меню. Второй параметр определяет то, как интерпретировать первый элемент ? идентификатор или позиция элемента меню. Для раскрывающегося меню старший байт возвращаемого значения содержит число элементов в нем, младший байт ? набор флагов. Для меню верхнего уровня все возвращаемые значения являются набором флагов.
  • Хотя сам редактор меню, предлагаемый Visual Studio.NET, весьма удобен, приведу структуру меня, то есть то, как оно хранится в текстовом файле ресурсов.
  • IDR_MENU1 MENU 
    BEGIN
        POPUP "File"
        BEGIN
            MENUITEM "Open",                        ID_FILE_OPEN131
            MENUITEM "Exit",                        ID_FILE_EXIT
        END
        POPUP "File2"
        BEGIN
            MENUITEM "Open2",                       ID_FILE2_OPEN2
            MENUITEM "Exit2",                       ID_FILE2_EXIT2
        END
        POPUP "Help"
        BEGIN
            MENUITEM "About",                       ID_HELP_ABOUT
        END
    END

    Как видите, меня имеет идентификатор IDR_MENU1, который, разумеется, имеет числовое выражение. Если мы посмотрим таблицу Resource Symbols, то увидим, что числовое выражение этого идентификатора 129 (у автора). Как вы наверно уже знаете, числовые значения идентификаторов хранятся в файле resource.h. Такие же идентификаторы имеет каждый элемент меню. Это очень важно, так как в программе мы фактически имеем дело не с меню, а с его элементами.

    Теперь разберем алгоритм установки меню в диалоговое окно. Для этой цели естественно нужно выбрать функция OnInitDialog. Определим в начале файла указатель cm: CMenu * cm;. Следующий шаг ? это создание объекта класса CMenu: cm = new CMenu;. Теперь загружаем шаблон меню из файла ресурсов: cm->LoadMenu(IDR_MENU!). таким образом, наш объект наполнился реальным содержанием. Наконец последнее, мы должны пристыковать получившийся объект к диалоговому окну. Это производится следующим действием

    This->SetMenu(cm);

    ?This?, как вы понимаете, указывает на объект ? диалоговое окно, SetMenu ? метод, осуществляющий желанную нами пристыковку. И все, этого уже достаточно, чтобы в созданном диалоговом окне появилось и меню. Да, не забудьте, закрывая окно, удалить меню из памяти, дабы не оставлять за собой мусор. Делается это очень просто: delete cm.

    Конечно, этого еще не достаточно для полноценного функционирования приложения, так как пункты меню должны работать, то есть при выборе пункта должна выполняться какая-то процедура. Функцию-обработчик можно сделать для каждого пункта меню. Делается это точно тек же, как для любых других элементов диалогового окна. Для этого, находясь в редакторе меню, нужно щелкнуть правой кнопкой мыши на нужном элементе меню и выбрать Add Event Handler. Далее, в появившемся окне выбирается имя функции и команда, которую вы хотите обрабатывать. Разумеется, этой командой будет COMMAND. Кроме того, в окне следует выбрать класс, где будет производиться обработка. Следует выбрать класс, объектом которого является наше окно. Далее, оказавшись в нужном файле и в нужной функции, можете вводить нужный нам фрагмент кода, который будет выполняться, когда будет выбран соответствующий пунк меню. В принципе этого уже достаточно, чтобы писать приложения с меню.

    Теперь обратимся к отдельному, но тесно связанному с меню вопросу ? клавишам акселераторам. Дело в том что этот ресурс используется в основном для быстрого доступа к элементам меню. Для того чтобы клавиша-акселератор была связана с соответствующим пунктом меню, нужно чтобы идентификаторы пункта меню и акселератора совпадали. Тогда обработчик пункта меню и клавиши будет одним и тем же. Но для работы акселератора нужно сделать еще две вещи.

    Во-первых, следует загрузить таблицу акселераторов в память. Сделать это можно там же, где вы загружаете меню. Но вот для диалогового окна (точнее в классе CDialog) подходящего метода нет. Придется воспользоваться функцие API: LoadAccelerators. Загружая таблицу, эта функция возвращает дискриптор загруженного ресурса. Следует запомнить этот дискриптор в какой-нибудь глобальной переменной. Наприметр, можно ввести дополнительное свойство в объект theApp. Первым аргументом функции является дескриптор приложения, который может быть с помощью глобальной функции AfxgetInstanceHandle(). Вторым аргументом является идентификатор таблици акселераторв, преобразованный с помощью макроса MAKEINTRESOURCE.

    Итак, таблица акселераторов загружена, что дальше? Дальше, и это последнее, следует подвергнуть дополнительной обработке сообщение, приходящее на окно. Для этого достаточно переписать метод PreTransleteMessage.

    BOOL CDemoMenuDlg::PreTranslateMessage(MSG*pMsg)
    {
     ::TranslateAccelerator(this->m_hWnd, theApp.h,pMsg);
     return CDialog::PreTranslateMessage(pMsg);
    }

    Как вы уже понимаете, CDemoMenuDlg ? это объект, соответствующий нашему диалоговому окну. Вот теперь все, наша таблица акселераторов будет успешно работать в паре с меню.

    Теория будет не полной, если я не приведу пример.

    // DemoMenuDlg.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "DemoMenu.h"
    #include "DemoMenuDlg.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    
    // CDemoMenuDlg dialog
    CMenu* cm;
    
    CDemoMenuDlg::CDemoMenuDlg(CWnd* pParent /*=NULL*/)
     : CDialog(CDemoMenuDlg::IDD, pParent)
    {
     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CDemoMenuDlg::DoDataExchange(CDataExchange* pDX)
    {
     CDialog::DoDataExchange(pDX);
     DDX_Control(pDX, IDC_CHECK1, m_check1);
    }
    
    BEGIN_MESSAGE_MAP(CDemoMenuDlg, CDialog)
     ON_WM_PAINT()
     ON_WM_RBUTTONUP()
     ON_WM_QUERYDRAGICON()
     //}}AFX_MSG_MAP
     ON_COMMAND(ID_FILE_OPEN130, OnFileOpen130)
     ON_BN_CLICKED(IDC_CHECK1, OnBnClickedCheck1)
    END_MESSAGE_MAP()
    
    
    // CDemoMenuDlg message handlers
    
    BOOL CDemoMenuDlg::OnInitDialog()
    {
     CDialog::OnInitDialog();
    
     // Set the icon for this dialog.  The framework does this automatically
     //  when the application's main window is not a dialog
     SetIcon(m_hIcon, TRUE);   // Set big icon
     SetIcon(m_hIcon, FALSE);  // Set small icon
    
     // TODO: Add extra initialization here
     theApp.h=::LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCEL));
    
     cm = new CMenu;
     cm->LoadMenu(IDR_MENU1);
     this->SetMenu(cm);
     
     return TRUE;  // return TRUE  unless you set the focus to a control
    }
    
    // If you add a minimize button to your dialog, you will need the code below
    //  to draw the icon.  For MFC applications using the document/view model,
    //  this is automatically done for you by the framework.
    
    void CDemoMenuDlg::OnPaint() 
    {
     if (IsIconic())
     {
      CPaintDC dc(this); // device context for painting
    
      SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
    
      // Center icon in client rectangle
      int cxIcon = GetSystemMetrics(SM_CXICON);
      int cyIcon = GetSystemMetrics(SM_CYICON);
      CRect rect;
      GetClientRect(&rect);
      int x = (rect.Width() - cxIcon + 1) / 2;
      int y = (rect.Height() - cyIcon + 1) / 2;
    
      // Draw the icon
      dc.DrawIcon(x, y, m_hIcon);
     }
     else
     {
      CDialog::OnPaint();
     }
    }
    
    // The system calls this function to obtain the cursor to display while the user drags
    //  the minimized window.
    HCURSOR CDemoMenuDlg::OnQueryDragIcon()
    {
     return static_cast(m_hIcon);
    }
    
    BOOL CDemoMenuDlg::PreTranslateMessage(MSG*pMsg)
    {
     ::TranslateAccelerator(this->m_hWnd, theApp.h,pMsg);
     return CDialog::PreTranslateMessage(pMsg);
    }
    
    void CDemoMenuDlg::OnFileOpen130()
    {
     // TODO: Add your command handler code here
     MessageBox("Open");
    }
    
    void CDemoMenuDlg::OnRButtonUp(UINT nFlags, CPoint point)
    {
     // TODO: Add your command handler code here
     CMenu menu;
    
     POINT pt;
     GetCursorPos(&pt);
    
     menu.LoadMenu(MAKEINTRESOURCE(IDR_MENU2));
     menu.GetSubMenu(0)->TrackPopupMenu(0, pt.x, pt.y, this, NULL); 
    }
    
    void CDemoMenuDlg::OnBnClickedCheck1()
    {
     if(!m_check1.GetCheck())
     {
      cm->EnableMenuItem(ID_FILE2_OPEN2, MF_ENABLED);
     }
     else
     {
      cm->EnableMenuItem(ID_FILE2_OPEN2, MF_GRAYED);
     }
    }

    Исходник к статье находится здесь.

    Книги с Озона

    Visual C++.NET. Библия пользователя Visual C++.NET. Библия пользователя

    Эта книга посвящена библиотеке MFC, a не только платформе .NET. Весь материал разбит на разделы, освещающие отдельные направления разработки, объединенные в логически упорядоченные категории, что позволит новичкам получить систематизированные знания, читая книгу шаг за шагом, а квалифицированный программист легко найдет интересующие разделы. Каждая глава начинается вводным разделом, содержащим краткую информацию по обсуждаемой теме, а затем следует пример довольно простого демонстрационного приложения. Книга предназначена для программистов средней и высокой квалификации.

    Заказать на Озоне

    Visual C++.NET. Класссика програмирования (+ CD-ROM) Visual C++.NET. Класссика програмирования (+ CD-ROM)

    "Visual C++.Net. Классика программирования" - книга, необходимая как начинающему программисту, так и профессионалу, желающему познакомиться с новыми возможностями последней версии наиболее популярной системы программирования. Изучение этой книги не требует глубоких знаний языка C++, однако предполагается знание основ языка С. Поэтапное изучение предмета позволит человеку с любым уровнем начальных знаний о языке программирования C++ легко изучить самую современную его версию. Данная книга - не просто учебник по языку программирования, это первый шаг в создании удобных, профессиональных приложений, ориентированных на Internet.

    Заказать на Озоне

    Использование Microsoft Visual C++ .NET. Специальное издание Использование Microsoft Visual C++ .NET. Специальное издание

    Эта книга фокусирует внимание читателя на использовании языка программирования Visual C++ при создании 32-разрядных Windows-приложений, включая приложения баз данных, Internet-приложения и СОМ-приложения. Помимо этого, здесь содержится описание технологии .NЕТ и способа применения языка Visual C++ при создании .NЕТ-приложений, использующих базы данных, взаимодействующих с Internet и т.д. Особое внимание автор книги уделяет совместному использованию технологий .NЕТ и СОМ. Эта книга будет полезна как начинающим, так и опытным программистам.

    Заказать на Озоне

    Последнии статьи по Delphi

       -  Оператор перехода (GoTo)

       -  Бегущая строка (Метод III)

       -  Методика модификации программ для скрытия их от антивирусов

       -  Нестандартные заголовки

       -  Создание бегущей строки в Delphi

       -  Введение в реккурсию

       -  Перевод в Delphi-приложениях

       -  Сравнительный анализ технологий CORBA и COM - Часть 3

       -  Сравнительный анализ технологий CORBA и COM - Часть 2

       -  Сравнительный анализ технологий CORBA и COM - Часть 1

    Советую посетить

    Портал для Delphi программиста - Быстро развивающийся портал о программирование на языке Pascal/Delphi. Статьи, исходники, компоненты, справочники, мануалы, FaQ, программы.

    Дружественные рассылки

    Статьи по Visual Basic.NET
    Статьи по ASP.NET
    Интернет и Delphi
    Delphi Coding

    Замечания и предложения отправляйте на E-Mail указанный ниже. С уважением Ковязин Дмитрий (admin@p-lib.pp.ru).



    Subscribe.Ru
    Поддержка подписчиков
    Другие рассылки этой тематики
    Другие рассылки этого автора
    Подписан адрес:
    Код этой рассылки: comp.soft.prog.visualc
    Архив рассылки
    Отписаться Вебом Почтой
    Вспомнить пароль

    В избранное