|
|
|
Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Соблюдайте общие правила форума
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как «свернуть» программу в трей.
3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры — внедрение в удаленное адресное прстранство)
… (продолжение следует) …
Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка — 60 дней. Последующие попытки — бан.
Мат в разделе — бан на три месяца…
Полезные ссылки: MSDN Library
FAQ раздела
Поиск по разделу
Как правильно задавать вопросы
Выразить свое отношение к модераторам раздела можно здесь: Rouse_,
Krid
Изменить имя класса окна во время выполнении программы
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Доброго времени суток всем. Допустим класс моей формы называется TForm1. Хочу сменить это название на абсолютно любое прямо при выполнении программы. Как это сделать? Сообщение отредактировано: Alexander N — 02.02.10, 16:19 |
Marriage |
|
Зачем? |
Alexander N |
|
ДЛя защиты от закрытия с помощью другой проги. |
Marriage |
|
По идее никак … |
Alexander N |
|
А название класса хранится в памяти как строка? Если да, то как ее найти? |
Riply |
|
Цитата Alexander N @ 02.02.10, 17:04 ДЛя защиты от закрытия с помощью другой проги. Я бы смотрела не в сторону затруднения нахождения (если окно есть — найдут все равно), |
kero_xmemor |
|
Alexander N
С такими запросами — что вы тут делаете? Вам — в ядро |
Riply |
|
Цитата Alexander N @ 02.02.10, 17:39 А название класса хранится в памяти как строка? Если да, то как ее найти? Цитата kero_xmemor @ 03.02.10, 06:43 Alexander N Цитата С такими запросами — что вы тут делаете? Вам — в ядро Эмн… Стесняюсь спросить… А в какое ядро ? |
Gonarh |
|
Цитата kero_xmemor @ 03.02.10, 06:43 Alexander N
С такими запросами — что вы тут делаете? Вам — в ядро
[offtop]как в какое? в ядерное конечно |
Lumen |
|
Имена классов окон хранятся в таблице атомов в ядре. |
Riply |
|
Цитата Lumen @ 03.02.10, 10:59 Имена классов окон хранятся в таблице атомов в ядре. И какой только гадости в ядро не понапихали |
leo |
|
Цитата Alexander N @ 02.02.10, 16:19 Допустим класс моей формы называется TForm1. Хочу сменить это название на абсолютно любое прямо при выполнении программы. Как это сделать? Можно просто изменить название класса окна до его регистрациисоздания. Для этого достаточно переопределить метод TForm1.CreateParams 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 |
|
Я вообще подумал что автор хочет изменить класс уже существующего окна. |
Alexander N |
|
Цитата 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 |
|
При завершении работы компьютера в целом? |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Система, Windows API
- Следующая тема
[ 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
Привет. Подскажите, возможно ли изменить стандартное название класса окна? Я хочу, чтобы класс моего окна по-другому назывался.
__________________
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 |
|||||||
А как переименовать? Вот я создаю форму.
Дальше идёт конструктор.
Как переименовать?
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.