Как изменить класс окна

Нравится ресурс?

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    !
    user posted image

    Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

    Соблюдайте общие правила форума

    Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
    1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
    2. Как «свернуть» программу в трей.
    3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
    4. Как запустить программу/файл? (и дождаться ее завершения)
    5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры — внедрение в удаленное адресное прстранство)
    … (продолжение следует) …


    Внимание:
    Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
    Повторная попытка — 60 дней. Последующие попытки — бан.
    Мат в разделе — бан на три месяца…


    Полезные ссылки:
    user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


    Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

    >
    Изменить имя класса окна во время выполнении программы

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему

      


    Сообщ.
    #1

    ,
    02.02.10, 16:19

      Доброго времени суток всем. Допустим класс моей формы называется TForm1. Хочу сменить это название на абсолютно любое прямо при выполнении программы. Как это сделать?

      Сообщение отредактировано: Alexander N — 02.02.10, 16:19


      Marriage



      Сообщ.
      #2

      ,
      02.02.10, 16:26

        Зачем?


        Alexander N



        Сообщ.
        #3

        ,
        02.02.10, 17:04

          ДЛя защиты от закрытия с помощью другой проги.


          Marriage



          Сообщ.
          #4

          ,
          02.02.10, 17:09

            По идее никак …


            Alexander N



            Сообщ.
            #5

            ,
            02.02.10, 17:39

              А название класса хранится в памяти как строка? Если да, то как ее найти?


              Riply



              Сообщ.
              #6

              ,
              02.02.10, 21:34

                Цитата Alexander N @ 02.02.10, 17:04

                ДЛя защиты от закрытия с помощью другой проги.

                Я бы смотрела не в сторону затруднения нахождения (если окно есть — найдут все равно),
                а в сторону собственного «незакрывания» на стандартные команды.
                (Если закрывать будут силовыми методиками, то против лома… :) )


                kero_xmemor



                Сообщ.
                #7

                ,
                03.02.10, 06:43

                  Alexander N

                  С такими запросами — что вы тут делаете? Вам — в ядро :)


                  Riply



                  Сообщ.
                  #8

                  ,
                  03.02.10, 07:01

                    Цитата Alexander N @ 02.02.10, 17:39

                    А название класса хранится в памяти как строка? Если да, то как ее найти?

                    Цитата kero_xmemor @ 03.02.10, 06:43

                    Alexander N

                    Цитата
                    как ее найти?

                    С такими запросами — что вы тут делаете? Вам — в ядро

                    Эмн… Стесняюсь спросить… А в какое ядро ? :blush:
                    :)


                    Gonarh



                    Сообщ.
                    #9

                    ,
                    03.02.10, 09:02

                      Цитата kero_xmemor @ 03.02.10, 06:43

                      Alexander N

                      С такими запросами — что вы тут делаете? Вам — в ядро :)

                      [offtop]как в какое? в ядерное конечно :lol: [/offtop]


                      Lumen



                      Сообщ.
                      #10

                      ,
                      03.02.10, 10:59

                        Имена классов окон хранятся в таблице атомов в ядре.
                        Кое-что полезное можно почерпнуть из этой статьи: Инжект: лезем через окно
                        Ещё плагин Phantom как-то изменяет класс окна отладчика OllyDebug, можно его поковырять, посмотреть реализацию


                        Riply



                        Сообщ.
                        #11

                        ,
                        03.02.10, 11:27

                          Цитата Lumen @ 03.02.10, 10:59

                          Имена классов окон хранятся в таблице атомов в ядре.
                          Кое-что полезное можно почерпнуть из этой статьи: Инжект: лезем через окно
                          Ещё плагин Phantom как-то изменяет класс окна отладчика OllyDebug, можно его поковырять, посмотреть реализацию

                          И какой только гадости в ядро не понапихали :)
                          Век живи — век учись.
                          Спасибо :)


                          leo



                          Сообщ.
                          #12

                          ,
                          03.02.10, 11:35

                            Цитата Alexander N @ 02.02.10, 16:19

                            Допустим класс моей формы называется TForm1. Хочу сменить это название на абсолютно любое прямо при выполнении программы. Как это сделать?

                            Можно просто изменить название класса окна до его регистрациисоздания. Для этого достаточно переопределить метод TForm1.CreateParams

                            ExpandedWrap disabled

                              type

                                TForm1 = class(TForm)

                                …

                                protected

                                  procedure CreateParams(var Params: TCreateParams); override;

                                end;

                              procedure TForm1.CreateParams(var Params: TCreateParams);

                              begin

                                inherited CreateParams(Params);

                                Params.WinClassName:=’Abracadabra’;

                              end;

                            Добавлено 03.02.10, 11:45

                            Цитата Alexander N @ 02.02.10, 17:04

                            ДЛя защиты от закрытия с помощью другой проги

                            Если имеется ввиду закрытие через посылку сообщений WM_CLOSE или WM_SYSCOMMAND, то также можно переопределить метод TForm1.WndProc или заменить WindowProc, в котором игнорировать указанные сообщеня, если они посланы не из твоего главного потока: InSendMessage = true


                            Lumen



                            Сообщ.
                            #13

                            ,
                            03.02.10, 11:55

                              Я вообще подумал что автор хочет изменить класс уже существующего окна. :) А так да, при создании можно подменить название на любое. Если окно не свое, то можно ещё перехватить RegisterClass.
                              ЗЫ: Кроме WM_CLOSE и подобных ещё придется сделать что-то с TerminateProcess


                              Alexander N



                              Сообщ.
                              #14

                              ,
                              03.02.10, 12:09

                                Цитата leo @ 03.02.10, 11:35

                                Можно просто изменить название класса окна до его регистрациисоздания

                                Как вариант очень годится, хотя предполагалось изначально менять имя рендомно по таймеру.

                                Цитата Lumen @ 03.02.10, 11:55

                                Кроме WM_CLOSE и подобных ещё придется сделать что-то с TerminateProcess

                                Это тоже будет.

                                Цитата leo @ 03.02.10, 11:35

                                Если имеется ввиду закрытие через посылку сообщений WM_CLOSE или WM_SYSCOMMAND, то также можно переопределить метод TForm1.WndProc или заменить WindowProc, в котором игнорировать указанные сообщеня, если они посланы не из твоего главного потока: InSendMessage = true

                                А сообщения от системы? ПРи завершени работы к примеру.

                                ВАжное замечание: из-за недостатка материала просьба не ограничиваться только Delphi, если это можно сделать на другом языке.

                                Сообщение отредактировано: Alexander N — 03.02.10, 12:11


                                Lumen



                                Сообщ.
                                #15

                                ,
                                03.02.10, 12:14

                                  При завершении работы компьютера в целом?
                                  Тогда надо перехватывать WM_QUERYENDSESSION

                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                                  0 пользователей:

                                  • Предыдущая тема
                                  • Delphi: Система, Windows API
                                  • Следующая тема

                                  Рейтинг@Mail.ru

                                  [ Script execution time: 0,0426 ]   [ 16 queries used ]   [ Generated: 10.02.23, 13:40 GMT ]  

                                  I am currently trying to translate a few WIN32API functions to Java using JNI. One of those functions is RegisterClassEx. Usually, I think you would specify a different callback function for every window class you register, but since I’m translating the callback to Java as well this doesn’t work.

                                  So the current plan is to append a jobject (defined as _jobject*) to the window class and work with that in the callback. Problem is: you can only change data attached to a window class using a HWND. The MSDN documentation to the best of my knowledge doesn’t specify a function that can modify a window class using only a window class ATOM or the name.

                                  Thus my question: Is there a way to change a window class (using something like SetClassLongPtr), without having to use a valid HWND?

                                  Java side (I’ll eventually add a public function that does what I actually need done):

                                  public class c_winjni implements i_jnisystem {
                                      public interface i_wnd_proc {
                                          public int wnd_proc(long il_hwnd, int im_message, long im_wparam, long im_lparam);
                                      }
                                  
                                      private class c_wndclassex {
                                          public int im_style = 0;
                                          public i_wnd_proc ds_wnd_proc = null;
                                          public int im_cls_extra = 0;
                                          public int im_wnd_extra = 0;
                                          public long il_instance = 0L;
                                          public long il_icon = 0L;
                                          public long il_small_icon = 0L;
                                          public long il_cursor = 0L;
                                          public long il_background = 0L;
                                          public String str_menu_name = null;
                                          public String str_class_name = null;
                                      }
                                  
                                      private static native short registerClassEx(c_wndclassex ds_wcx, int[] imr_error);
                                  }
                                  

                                  C++ side:

                                  LRESULT CALLBACK default_window_callback_proc(HWND ds_hwnd, UINT im_message, WPARAM im_w_param, LPARAM im_l_param) {
                                      return DefWindowProc(ds_hwnd, im_message, im_w_param, im_l_param);
                                  }
                                  
                                  /*
                                   * Class:     c_winjni
                                   * Method:    registerClassEx
                                   * Signature: (Lc_winjni/c_wndclassex;[I)S
                                   */
                                  JNIEXPORT_EX jshort JNICALL Java_c_1winjni_registerClassEx
                                      (JNIEnv *ads_env, jclass /*jds_class*/, jobject jds_wcx, jintArray jimr_error)
                                  JNI_CPPEXCEPTION_TRAP_BEGIN {
                                      c_jnienv jds_env(ads_env);
                                  
                                      jint *aim_error = NULL;
                                      if (jimr_error && jds_env.get_array_length(jimr_error) > 0) {
                                          aim_error = jds_env.get_array_elements(jimr_error, NULL);
                                      }
                                  
                                      WNDCLASSEX ds_wcx;
                                      ds_wcx.cbSize = sizeof(WNDCLASSEX);
                                      ds_wcx.style = jds_env.get_int_field(jds_wcx, "im_style");
                                  
                                      // Imagine I'm checking whether field ds_wnd_proc in object jds_wcx is null.
                                      // If it is, use the default callback (as shown below).
                                      // If it isn't, set ds_wcx.lpfnWndProc to some other callback that reads
                                      // custom class data and calls a Java function of the object attached to the window class.
                                      ds_wcx.lpfnWndProc = default_window_callback_proc;
                                  
                                      ds_wcx.cbClsExtra = jds_env.get_int_field(jds_wcx, "im_cls_extra") + sizeof(LONG_PTR);
                                      ds_wcx.cbWndExtra = jds_env.get_int_field(jds_wcx, "im_wnd_extra");
                                      ds_wcx.hInstance = (HINSTANCE) jds_env.get_long_field(jds_wcx, "il_instance");
                                      ds_wcx.hIcon = (HICON) jds_env.get_long_field(jds_wcx, "il_icon");
                                      ds_wcx.hIconSm = (HICON) jds_env.get_long_field(jds_wcx, "il_small_icon");
                                      ds_wcx.hCursor = (HCURSOR) jds_env.get_long_field(jds_wcx, "il_cursor");
                                      ds_wcx.hbrBackground = (HBRUSH) jds_env.get_long_field(jds_wcx, "il_background");
                                      ct_jstring<TCHAR, 256> str_menu_name(ads_env, (jstring) jds_env.get_string_field(jds_wcx, "str_menu_name"));
                                      ds_wcx.lpszMenuName = str_menu_name.get_data();
                                      ct_jstring<TCHAR, 256> str_class_name(ads_env, (jstring) jds_env.get_string_field(jds_wcx, "str_class_name"));
                                      ds_wcx.lpszClassName = str_class_name.get_data();
                                  
                                      jshort result = RegisterClassEx(&ds_wcx);
                                      if (result == NULL && aim_error) {
                                          *aim_error = GetLastError();
                                      }
                                  
                                      // commit changes and invalidate pointer
                                      if (aim_error) {
                                          jds_env.release_array_elements(jimr_error, aim_error, 0);
                                      }
                                      return result;
                                  } JNI_CPPEXCEPTION_TRAP_END2(ads_env, 0)
                                  

                                  I am currently trying to translate a few WIN32API functions to Java using JNI. One of those functions is RegisterClassEx. Usually, I think you would specify a different callback function for every window class you register, but since I’m translating the callback to Java as well this doesn’t work.

                                  So the current plan is to append a jobject (defined as _jobject*) to the window class and work with that in the callback. Problem is: you can only change data attached to a window class using a HWND. The MSDN documentation to the best of my knowledge doesn’t specify a function that can modify a window class using only a window class ATOM or the name.

                                  Thus my question: Is there a way to change a window class (using something like SetClassLongPtr), without having to use a valid HWND?

                                  Java side (I’ll eventually add a public function that does what I actually need done):

                                  public class c_winjni implements i_jnisystem {
                                      public interface i_wnd_proc {
                                          public int wnd_proc(long il_hwnd, int im_message, long im_wparam, long im_lparam);
                                      }
                                  
                                      private class c_wndclassex {
                                          public int im_style = 0;
                                          public i_wnd_proc ds_wnd_proc = null;
                                          public int im_cls_extra = 0;
                                          public int im_wnd_extra = 0;
                                          public long il_instance = 0L;
                                          public long il_icon = 0L;
                                          public long il_small_icon = 0L;
                                          public long il_cursor = 0L;
                                          public long il_background = 0L;
                                          public String str_menu_name = null;
                                          public String str_class_name = null;
                                      }
                                  
                                      private static native short registerClassEx(c_wndclassex ds_wcx, int[] imr_error);
                                  }
                                  

                                  C++ side:

                                  LRESULT CALLBACK default_window_callback_proc(HWND ds_hwnd, UINT im_message, WPARAM im_w_param, LPARAM im_l_param) {
                                      return DefWindowProc(ds_hwnd, im_message, im_w_param, im_l_param);
                                  }
                                  
                                  /*
                                   * Class:     c_winjni
                                   * Method:    registerClassEx
                                   * Signature: (Lc_winjni/c_wndclassex;[I)S
                                   */
                                  JNIEXPORT_EX jshort JNICALL Java_c_1winjni_registerClassEx
                                      (JNIEnv *ads_env, jclass /*jds_class*/, jobject jds_wcx, jintArray jimr_error)
                                  JNI_CPPEXCEPTION_TRAP_BEGIN {
                                      c_jnienv jds_env(ads_env);
                                  
                                      jint *aim_error = NULL;
                                      if (jimr_error && jds_env.get_array_length(jimr_error) > 0) {
                                          aim_error = jds_env.get_array_elements(jimr_error, NULL);
                                      }
                                  
                                      WNDCLASSEX ds_wcx;
                                      ds_wcx.cbSize = sizeof(WNDCLASSEX);
                                      ds_wcx.style = jds_env.get_int_field(jds_wcx, "im_style");
                                  
                                      // Imagine I'm checking whether field ds_wnd_proc in object jds_wcx is null.
                                      // If it is, use the default callback (as shown below).
                                      // If it isn't, set ds_wcx.lpfnWndProc to some other callback that reads
                                      // custom class data and calls a Java function of the object attached to the window class.
                                      ds_wcx.lpfnWndProc = default_window_callback_proc;
                                  
                                      ds_wcx.cbClsExtra = jds_env.get_int_field(jds_wcx, "im_cls_extra") + sizeof(LONG_PTR);
                                      ds_wcx.cbWndExtra = jds_env.get_int_field(jds_wcx, "im_wnd_extra");
                                      ds_wcx.hInstance = (HINSTANCE) jds_env.get_long_field(jds_wcx, "il_instance");
                                      ds_wcx.hIcon = (HICON) jds_env.get_long_field(jds_wcx, "il_icon");
                                      ds_wcx.hIconSm = (HICON) jds_env.get_long_field(jds_wcx, "il_small_icon");
                                      ds_wcx.hCursor = (HCURSOR) jds_env.get_long_field(jds_wcx, "il_cursor");
                                      ds_wcx.hbrBackground = (HBRUSH) jds_env.get_long_field(jds_wcx, "il_background");
                                      ct_jstring<TCHAR, 256> str_menu_name(ads_env, (jstring) jds_env.get_string_field(jds_wcx, "str_menu_name"));
                                      ds_wcx.lpszMenuName = str_menu_name.get_data();
                                      ct_jstring<TCHAR, 256> str_class_name(ads_env, (jstring) jds_env.get_string_field(jds_wcx, "str_class_name"));
                                      ds_wcx.lpszClassName = str_class_name.get_data();
                                  
                                      jshort result = RegisterClassEx(&ds_wcx);
                                      if (result == NULL && aim_error) {
                                          *aim_error = GetLastError();
                                      }
                                  
                                      // commit changes and invalidate pointer
                                      if (aim_error) {
                                          jds_env.release_array_elements(jimr_error, aim_error, 0);
                                      }
                                      return result;
                                  } JNI_CPPEXCEPTION_TRAP_END2(ads_env, 0)
                                  

                                  0 / 0 / 0

                                  Регистрация: 28.02.2016

                                  Сообщений: 70

                                  1

                                  Смена класса окна

                                  20.02.2020, 06:01. Показов 586. Ответов 5


                                  Привет.

                                  Подскажите, возможно ли изменить стандартное название класса окна?
                                  Имеется ввиду, те самые название, которые выдаёт компилятор.
                                  Типа, WindowsForms10.Window.8.app.0.2004eee.

                                  Я хочу, чтобы класс моего окна по-другому назывался.
                                  Возможно ли такое?

                                  __________________
                                  Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



                                  0



                                  Фрилансер

                                  761 / 458 / 146

                                  Регистрация: 06.01.2017

                                  Сообщений: 4,814

                                  20.02.2020, 11:01

                                  2

                                  Цитата
                                  Сообщение от Паразиттт
                                  Посмотреть сообщение

                                  Я хочу, чтобы класс моего окна по-другому назывался.

                                  так переименуйте ваш класс)
                                  в чем проблема-то?))



                                  0



                                  Паразиттт

                                  0 / 0 / 0

                                  Регистрация: 28.02.2016

                                  Сообщений: 70

                                  20.02.2020, 14:19

                                   [ТС]

                                  3

                                  А как переименовать?

                                  Вот я создаю форму.

                                  C#
                                  1
                                  
                                  public class Form1 : System.Windows.Forms.Form{...

                                  Дальше идёт конструктор.

                                  C#
                                  1
                                  
                                  public Form1(){...

                                  Как переименовать?
                                  Это надо какие-то свойства для this устанавливать?



                                  0



                                  Фрилансер

                                  761 / 458 / 146

                                  Регистрация: 06.01.2017

                                  Сообщений: 4,814

                                  20.02.2020, 14:50

                                  4

                                  Цитата
                                  Сообщение от Паразиттт
                                  Посмотреть сообщение

                                  Как переименовать?

                                  выделяете мышкой Form1 и дважды нажимаете Ctrl+R если у вас Visual Studio
                                  или просто выделяете и ПКМ -> Переименовать



                                  1



                                  0 / 0 / 0

                                  Регистрация: 28.02.2016

                                  Сообщений: 70

                                  21.02.2020, 08:13

                                   [ТС]

                                  5

                                  FateOri, не получается. Всё равно даёт такой класс. WindowsForms10.Window.8.app.0.2004eee.



                                  0



                                  Фрилансер

                                  761 / 458 / 146

                                  Регистрация: 06.01.2017

                                  Сообщений: 4,814

                                  21.02.2020, 11:28

                                  6

                                  Цитата
                                  Сообщение от Паразиттт
                                  Посмотреть сообщение

                                  WindowsForms10.Window.8.app.0.2004eee.

                                  может вы об имени сборки говорите?)

                                  посмотрите в свойствах проекта там должно быть «Имя сборки» вот его и меняйте



                                  0



                                  IT_Exp

                                  Эксперт

                                  87844 / 49110 / 22898

                                  Регистрация: 17.06.2006

                                  Сообщений: 92,604

                                  21.02.2020, 11:28

                                  6

                                  Ресурсы

                                  Понятие ресурсов

                                  Структура EXE-файла для Windows такова, что в его конец могут быть записаны некоторые данные, совершенно не зависящие от самой программы. Они называются ресурсами. Ресурсы могут редактироваться совершенно раздельно, хотя находятся в том же файле, где код и данные. При загрузке программы на выполнение, ресурсы обычно не загружаются в память, а это делается лишь по запросу от программы. В ресурсах программа может хранить любые данные, какого угодно размера. Но есть стандартные типы ресурсов, такие как иконки, битовые образы, курсоры, диалоги, меню. Большинство диалоговых окон не создаются программным путем, а просто их шаблоны загружаются из ресурсов. Сами шаблоны, как и другие ресурсы, редактируются визуально с помощью специальных ресурсных редакторов. При сборке проекта приложения, ресурсы добавляются к EXE-файлу уже после связывания. Для описания ресурсов существует специальный язык, а сами описания хранятся в текстовых файлах с расширением rc. Раньше программисты вручную писали сценарии ресурсов на языке ресурсов, сейчас используются визуальные редакторы. Перед добавлением к исполняемому файлу, сценарии преобразуются в бинарный вид с помощью компилятора ресурсов, в результате получается файл с расширением res. Как правило, все эти шаги выполняются автоматически при работе из интегрированной среды Visual C++. Заметим, что «ручное» редактирование ресурсных сценариев требуется сейчас уже очень редко, лишь при определении нестандартных ресурсов в сложных проектах. Каждый ресурс имеет свой уникальный идентификатор. Это может быть либо строка, либо число (константа). Числа можно использовать всегда, а строки – не всегда. Редактор ресурсов из Visual C++ помещает имена констант в файл resource.h, который нужно включить в файлы программы. Стандартные идентификаторы хранятся в файле afxres.h, который обычно используется автоматически ресурсным редактором.

                                  Меню

                                  Меню, как правило, создаются визуально. В Visual C++ за это отвечает редактор ресурсов. Среда автоматически добавляет в проект сценарий ресурсов. При создании меню, для отдельных пунктов могут быть установлены опции выделения серым цветом (в этом случае при выполнении программы пункт меню будет недоступен), вставки разделительной горизонтальной черты, перехода на новую строку (в этом случае пункты верхнего уровня будут начинаться с новой строки, а нижнего – в новом столбце через вертикальную черту). Меню, как отдельному ресурсу, должен быть присвоен числовой или символьный идентификатор. При редактировании символьные идентификаторы заключаются в кавычки. Также, каждому пункту меню должен быть присвоен уникальный числовой идентификатор. Это позволит программе реагировать на выбор пункта в меню, и будет вызываться соответствующий обработчик. По принятому соглашению, все идентификаторы пунктов меню начинаются с IDM_. В самих названиях пунктов можно указывать ключевые клавиши, поставив перед буквой символ &. В этом случае, если меню активно, пункт можно выбрать также и с клавиатуры.

                                  Включение меню в окно приложения

                                  Когда ресурс меню уже создан, его можно использовать в окне программы. Это можно сделать, указывая меню при создании окна: строковый идентификатор ресурса меню нужно указать в качестве последнего параметра в функции Create():

                                  this->Create(0, «Приложение с меню», WS_OVERLAPPEDWINDOW, rectDefault, 0, «MYMENU»);

                                  В результате будет создано окно с меню. Но, для того чтобы меню можно было использовать, необходимо создать обработчики сообщения WM_COMMAND для каждого пункта меню. Если для какого-то пункта нет обработчика, то MFC заблокирует этот пункт (он будет выделен серым цветом).

                                  Сообщение WM_COMMAND

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

                                  ON_COMMAND(Идентификатор, ИмяОбработчика);

                                  Каждый обработчик для WM_COMMAND должен возвращать значение void. Обработчики не имеют параметров. Имя выбирается произвольно, обычно используется префикс On. Таким образом, можно написать обработчики для каждого пункта меню.

                                  Акселераторы

                                  Это специальный ресурс, не имеющий визуального представления. Он представляет собой таблицу из комбинаций клавиш и соответствующих им идентификаторов команд. Таблица может быть загружена для конкретного окна с помощью функции с прототипом:

                                  BOOL CFrameWnd::LoadAccelTable(LPCSTR ResourceName);

                                  После загрузки таблицы акселераторов, нажатие заданных в ней комбинаций клавиш приводит к автоматической генерации сообщения WM_COMMAND с идентификатором, определенным в этой таблице для данной комбинации клавиш. Акселераторы легко создавать в среде Visual C++. Для каждого элемента таблицы нужно нажать желаемую клавишу или их комбинацию, и указать числовой идентификатор. Если указать идентификаторы, которые уже использовались в меню, то мы получим клавиши быстрого доступа, дублирующие команды меню.

                                  Окна сообщений

                                  Это простейшие диалоговые окна, предопределенные в системе. Для создания окна сообщения используется функция с прототипом:

                                  int CWnd::MessageBox(LPCSTR MessageText, LPCSTR WindowTitle = 0, UINT MessageBoxType = MB_OK);

                                  Параметр MessageText определяет само сообщение. Параметр WindowTitle — заголовок окна сообщения. Параметр MessageBoxType задает стиль окна, иконку, отображаемую слева от сообщения, и одну, или несколько кнопок. Этот параметр задается комбинацией констант с помощью операции «|», начинающихся на префикс MB_. Все наборы кнопок заранее определены. Функция возвращает идентификатор нажатой кнопки: IDABORT, IDRETRY, IDIGNORE, IDCANCEL, IDNO, IDYES, или IDOK. Функция MessageBox(…) выполняет все действия по созданию, отображению и удалению окна, а также обработку сообщений. Программист не должен об этом заботиться.

                                  Иконки и курсоры

                                  Иконки и курсоры являются ресурсами и обычно хранятся в области ресурсов исполняемого файла.

                                  Создание иконки и курсора

                                  Для создания иконки и курсора нужно использовать ресурсный редактор. Иконки сохраняются в файлах с расширением ico, а курсоры – в файлах с расширением cur. Все курсоры имеют размер 32×32. Обычно используются монохромные курсоры. Каждый курсор имеет так называемую горячую точку, по которой определяется положение курсора на экране. Она может располагаться в любом месте курсора. Для курсоров типа «указатель» это обычно вершина указателя. Иконки могут иметь размер 16х16, 32х32 и 48х48. Последний размер обычно не используется. Иконки могут иметь 16 или 256 цветов. При использовании редактора ресурсов среды Visual C++ 4.0 и выше иконки всех размеров можно хранить в одном файле, что обычно и делается. Для современных приложений обязательно наличие иконок размером как 16х16, так и 32х32.

                                  Загрузка иконки и курсора из ресурсов

                                  Для загрузки иконок и курсоров удобно использовать функции Win API. Перед рассмотрением этих функций следует рассмотреть понятие дескриптора.

                                  Дескриптор – это 32-разрядное беззнаковое целое значение, которое идентифицирует объект в Windows.

                                  При традиционном SDK-программировании дескрипторы используются очень широко. Так, свои дескрипторы имеют иконки, курсоры и само приложение. Для дескрипторов каждого объекта существует свой тип, например, HICON, HCURSOR, HINSTANCE. Будем предполагать, что в декларировании класса основного окна (речь идет о классе С++) объявлены переменные m_hIconSmall, m_hIconBig, m_hCursor – соответственно дескрипторы иконки 16х16, иконки 32х32 и курсора. Тогда для загрузки иконок и курсора нужно выполнить следующий код:

                                  // Получить дескриптор модуля (приложения)
                                  HINSTANCE hInst = AfxGetInstanceHandle();
                                  // Загрузить иконку 16х16
                                  m_hIconSmall = (HICON) ::LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
                                  // Загрузить иконку 32x32 
                                  m_hIconBig = (HICON) ::LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON),IMAGE_ICON,32,32,LR_DEFAULTCOLOR); 
                                  // Загрузить курсор
                                  m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR);

                                  Сначала мы получаем дескриптор модуля с помощью глобальной функции MFC AfxGetInstanceHandle(). Затем мы загружаем маленькую и большую иконки с помощью функции Win API LoadImage(…), и получаем их дескрипторы. Эта функция позволяет загружать изображения из ресурсов и из файлов. И, наконец, мы загружаем курсор уже с помощью функции MFC LoadCursor(…), члена класса CWinApp. Функция AfxGetApp() возвращает адрес объекта приложения.

                                  Изменение иконки и курсора окна

                                  После того как мы получили дескрипторы иконок и курсора, надо изменить класс окна. Класс окна надо изменять для установки курсора, а для установки иконок использовать функции MFC. Для этого используется API-функция SetClassLong(…), которая изменяет атрибут класса окна (здесь опять имеется в виду структура данных). Первый параметр этой функции – дескриптор окна. Дескриптор окна хранится в члене класса MFC CWnd под названием m_hWnd. Если главным окном приложения является диалог, то для изменения иконки и курсора потребуется следующий код (он будет работоспособен и для обычных окон):

                                  // Устанавливаем курсор для диалогового окна.
                                  SetClassLong(m_hWnd, GCL_HCURSOR, (long) m_hCursor);
                                  // Делаем то же самое для всех элементов управления
                                  for(int i = 0; i < 0xDFFF; ++i)
                                  {
                                    CWnd *pCtrl = this->GetDlgItem(i); 
                                    if(pCtrl != 0) 
                                      SetClassLong(pCtrl->m_hWnd, GCL_HCURSOR, (long) m_hCursor);
                                  }
                                  // Устанавливаем иконки. Здесь можно использовать MFC.
                                  this->SetIcon(m_hIconBig, TRUE);
                                  this->SetIcon(m_hIconSmall, FALSE);

                                  Сначала, мы модифицируем курсор в оконном классе самого окна. Затем, то же самое проделываем со всеми элементами управления, которые есть или могут быть в диалоговом окне (если их нет в окне, то ничего страшного не произойдет). Мы перебираем все возможные идентификаторы, и, если элемент присутствует, изменяем его оконный класс. И, наконец, мы изменяем большую и маленькую иконки.

                                  Стандартные иконки и курсоры

                                  Часто в программах необходимо использовать курсоры и иконки, уже предопределенные в Windows. Для этого можно использовать или функцию API LoadImage(…), или функции MFC LoadStandardIcon(…) и LoadStandardCursor(…). Работа со стандартными курсорами и иконками почти ничем не отличается от работы с пользовательскими курсорами и иконками. Для стандартных иконок есть предопределенные идентификаторы с префиксом IDI_, а для стандартных курсоров – с префиксом IDC_. Например, стандартный курсор в виде «песочных часов» имеет идентификатор IDC_WAIT.

                                  Понравилась статья? Поделить с друзьями:

                                  Читайте также:

                                • Как изменить класс обслуживания аэрофлот
                                • Как изменить класс дома самп
                                • Как изменить класс jquery
                                • Как изменить клаву на сяоми
                                • Как изменить клаву на андроиде

                                • 0 0 голоса
                                  Рейтинг статьи
                                  Подписаться
                                  Уведомить о
                                  guest

                                  0 комментариев
                                  Старые
                                  Новые Популярные
                                  Межтекстовые Отзывы
                                  Посмотреть все комментарии