Главная
Пишем собственный screencapturer для Windows. Часть 1 Версия в формате PDF Версия для печати Отправить на e-mail

В повседневной работе с Windows иногда , однако, все же возникает потребность в получений копий снимков с текущего рабочего стола

Windows. Для этого есть масса свободных или платных программ, а мы напишем свою. Тем боле, займет это очень мало времени. Для этого нам

нужно только работающий компьютер с установленной операционной системой Windows, Microsoft Visual Studio 2003  и  конечно,  MSDN . Сама процедура разработка будет описана пошагово,  там же  будут  те части программного  кода, которые будут нами созданы.

 

  1. Как обычно, создаем шаблон программы. Для этого запускаем Microsoft Visual Studio 2003 , выбираем “New Project…”, затем “Visual C++”. В этом меню выбираем “MFC Application”. Выбираем путь где будет расположен наш проект и вводим название “screencapture”. (Хотя каждый может ввести любое название J )  Жмем «ОК». Дальше мы выбираем «Application Type» - “Dialog based”. Если кто желает подарить другу или подруге свою программу, то нужно выбрать  Use MFC in static library”. Все остальные настройки можно оставить без изменений.
  1. Открываем проект. Компилируем его, чтобы увидеть, то  что мы имеем сейчас.  Для начала удаляем «TODO: Place dialog controls here.» и обе кнопки “OK  и  Cancel”.  Увеличим размеры окна, например сделаем их 850x650. Отредактируем заголовок программы и введем туда “Screen Capturer”

       Затем, идем в редактор ресурсом и редактируем иконку «IDR_MAINFRAME»

       Эта   икона в последствии будет нам использована, но поскольку

       стандартный вид не совсем удобный, нам надо то-то специфическое.

      Рисуем иконку новую на основе существующей или создаем новую.

  1. Теперь создаем в редакторе ресурсов новое меню. Добавляем «Add Resource», там выбираем “New-> Menu”. Переименовываем  его из “IDR_MENU1”  в  “IDR_MENU_TRAY”. Затем займемся редактированием самого меню. Назовем его к примеру “Action”, затем добавляем

в подпункты “Get Screen”, “Hide In Tray”, “Restore” и  “Exit”. Перед последним пунктом  нажмем клавишу «-» для того, чтобы отделить   Exit” от

остальных команд.

       4.  На этом с ресурсами все, и мы начнем программировать.  По логике работы программы, нам нужно, чтобы  программа была не видна

            в момент  получения снимка экрана. Значит, она должна находится в системном трее, той области, где приложение свернуто до

             размеров иконки. Сначала создадим  новую переменную типа NOTIFYICONDATA с именем tray_icon для класса CscreencaptureDlg.cpp

            Обозначим ее  как  public”. Это структура, которая будет использована для хранения данных  для обработки сообщений системного трея.

  1. Теперь займемся нашим меню. Создадим переменную типа CMenu и назовем ее “menu” опять же  для класса CscreencaptureDlg.cpp. Затем в переходим в этом классе к методу OniInitDialog() и после  комментариев  // TODO: Add extra initialization here

пишем такой код

 

            menu.LoadMenu(IDR_MENU_TRAY);

            SetMenu(&menu);

   

           Первая строка загружает в переменную меню из ресурсов, в вторая делает его видимы на окне нашего приложения.

           Компилируем программу и видим результат ее работы, - появляется наше меню.

           Теперь переходим снова в редактор ресурсов и назначаем обработчики событий для пунктов меню. Сначала

           добавляем обработчик к пункту “Exit”. Делаем правый клик мышью на выбранном нами пункте меню и из выпавшего списка опций

           выбираем “Add Event Handler…”. Затем выбираем обработчик типа COMMAND и связываем с классом CscreencaptureDlg.cpp.

          В открывшемся окне нам нужно ввести код обработчика.

 

            void CscreencaptureDlg::OnActionExit() {

            EndDialog(0);

              }

  

    Сперва мы создаем переменную типа int и присваиваем ей значение 1. Это сделано скорее с данью традиции,

     можно присвоить любое значение этого же типа. Потому что метод EndDialog (int someresult);

   принимает  значения этого типа. Сам же метод, согласно его описанию и названию, просто уничтожает модальное

   диалоговое  окно.

 

  1. Чтобы создать обработчик сообщений для системного трея, мы должны сделать следующее;  ввести в файл  Ressource.h

       добавляем идентификатор иконки:

 

<span style="font-size: 12pt; font-family: "Times New Roman","serif""><span>             </span></span><strong><span style="font-size: 12pt; font-family: "Times New Roman","serif"; color: windowtext">#define ID_TrayIcon<span>                </span>135</span></strong> 

 

      Число «135» взято произвольно, главное чтобы не совпадало с уже существующими ID ресурсов. Этот ID будет впоследствии использовано для

      обращения к иконке. Затем мы создаем обработчик события для системного трея -  в классу диалогового окна вводим новое сообщение:

   

      #define WM_TRAYICONNOTIFY WM_USER+1

 

            все сообщения типа WM_USER+1 представляют собой частные сообщения, определяемые самим пользователем.

           Затем в карту сообщений  добавляем собственно обработчик сообщений для трея

        

            ON_MESSAGE(WM_ICON, OnTrayIcon)

 

            После чего она будет выглядеть таким образом:

 

            BEGIN_MESSAGE_MAP(CscreencaptureDlg, CDialog)

                 ON_WM_SYSCOMMAND()

                 ON_WM_PAINT()

                ON_WM_QUERYDRAGICON()

                 //}}AFX_MSG_MAP

                 ON_COMMAND(ID_ACTION_EXIT, OnActionExit)

                 ON_COMMAND(ID_ACTION_HIDE, OnActionHide)

                 ON_MESSAGE(WM_ICON, OnTrayIcon)

                 ON_COMMAND(ID_ACTION_RESTORE, OnActionRestore)

             END_MESSAGE_MAP()

    

           И самое главное, надо добавить новый метод, который и собственно  будет обрабатывать это сообщение. Для этого мы добавим к   классу CscreencaptureDlg.cpp.

           такой метод, кликнув мышью на “Class View” ( « Вид Классов»)  и выбрав класс диалогового окна. В выпавшем меню выберем “Add..-> Add Function

           Новый метод  OnTrayIcon будет  возвращать значения типа LRESULT и принимать   WPARAM wp, LPARAM lp. Затем вводим внутрь его такой код:

 

       LRESULT CscreencaptureDlg::OnTrayIcon(WPARAM wp, LPARAM lp) {

             

      if(wp != tray_icon.uID || lp != WM_LBUTTONDBLCLK &&

       lp != WM_RBUTTONUP)

        return 0;

 

       // Получение подменю

      CMenu *SubMenu = menu.GetSubMenu(0);

   

      // Если была нажата правая кнопка мыши

      if(lp == WM_RBUTTONUP)

       {

        // Первый пункт меню выделяется "жирным" шрифтом

        SubMenu->SetDefaultItem(0, true);

        // Получение позиции курсора

        CPoint mouse;

        GetCursorPos(&mouse);

        // Установка окна, которое будет получать фокус

        // (в данном случае это иконка и связанное с ней меню)

        ::SetForegroundWindow(tray_icon.hWnd);

        // Отображение контекстного меню

        SubMenu->TrackPopupMenu(0, mouse.x, mouse.y, this);

         }

      // Если была дважды нажата левая кнопка мыши

       else if(lp == WM_LBUTTONDBLCLK)

        // Имитация выбора пункта меню по умолчанию

        ::SendMessage(tray_icon.hWnd, WM_COMMAND,

                      SubMenu->GetMenuItemID(0), 0);

          return 1;

           

      }

      

     

 

 

  7.   Далее мы в методе OniInitDialog()  класса CscreencaptureDlg.cpp. инициализируем  переменную структуры  NOTIFYICONDATA

       tray_icon

 

         memset(&tray_icon, 0, sizeof(NOTIFYICONDATA));

      // Размер структуры

      tray_icon.cbSize = sizeof(NOTIFYICONDATA);

      // Иконка

      tray_icon.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

      // Дескриптор окна, получающего сообщения из трея

      tray_icon.hWnd = m_hWnd;

      // Подсказка

      strcpy(tray_icon.szTip, "Get Screen");

      // Идентификатор обработчика

      tray_icon.uCallbackMessage = WM_ICON;

       // Установка флагов

      tray_icon.uFlags = NIF_TIP | NIF_MESSAGE | NIF_ICON;

      // Идентификатор иконки

    trya_icon.uID = ID_TrayIcon;

 

      

 

       8. Снова возвращаемся в редактор ресурсов к нашему меню и аналогичным способом добавляем обработчик к пункту   Hide In Tray”.

           Затем редактируем его код:

 

         void CscreencaptureDlg::OnActionHide()

        {

           

      ShowWindow(SW_HIDE);

            //окно минимизируется

     

     Shell_NotifyIcon(NIM_ADD, &trray_icon);

     // В трее появляется иконка

 

        }

           

           Затем компилируем программу. Мы видим, что после нажатия на пункт меню “Hide In Tray” появляется иконка в системном трее и окно исчезает.

          

      9. Аналогичным способом добавляем обработчик к  пункту меню “Restore”:

 

          void CscreencaptureDlg::OnActionRestore()

           {

            // Удаление иконки из трея

           Shell_NotifyIcon(NIM_DELETE, &tray_icon);

  

               // Отображение главного окна

            ShowWindow(SW_NORMAL);

          // Теперь фокус будет получать главное окно

           ::SetForegroundWindow(m_hWnd);        

 

         }

 

10.    Компилируем приложение, пробуем. Если не было синтаксических ошибок, то все работает. J. Теперь перейдем к самому главному, тому, для чего мы создали

       эту  программу.  Нам потребуется использования класса контекста устройства, для чего мы  создаем новую переменную для класса диалогового окна –

       CDC DC. Далее создаем новый метод GetScreen().

опубликовано
Добавить новыйПоиск
Добавить комментарий
Имя:
E-mail:
 
Веб-сайт:
Заголовок:
UBB-Код:
[b] [i] [u] [url] [quote] [code] [img] 
 
 
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
 
Security Image
Пожалуйста, введите проверочный код, который Вы видите на картинке.

Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved.

 
< Пред.


© www.aurov.com - Личный сайт Александра Юрова 2008 All rights reserved
Tags
адреса исправить submenu documents необходимо просто resources rbbs работает increment exists говоря line значение ccmdui 3000 bases text окно изменить изначально csize nodselected isubitem form updatedata layout invalid changecurrentbase Последний

Joomla Modul

Главная
Статьи
Творчество
Галерея
Кто он-лайн
Сейчас на сайте:
Гостей - 2
Jx Random Quote
"Well, I think if you say you're going to do something and don't do it, that's trustworthiness." -- George W. Bush