На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
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

Модераторы: Rouse_, Krid
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Почему не отрабатывает WM_GETFONT?
    Delphi XE2.
    Для формы делаю:
    ExpandedWrap disabled
      hFont := SendMessage(Self.Handle, WM_GETFONT, 0, 0);

    Но возвращает 0. Т.е. как будто у формы установлен системный шрифт.
    Почему так?

    А если сделать, например, так:
    ExpandedWrap disabled
      hFont := SendMessage(CheckBox1.Handle, WM_GETFONT, 0, 0);

    То возвращает корректный дескриптор.

    Тоже самое, например, для TPanel - hFont = 0.
    А для кнопки hFont - корректное значение.
      Вроде бы потому, что там у них формы/панели создаётся как некое виртуальное окно (точнее, ненастоящее виндовое) и потому такие особенности.
        Цитата Славян @
        Вроде бы потому, что там у них формы/панели создаётся как некое виртуальное окно (точнее, ненастоящее виндовое) и потому такие особенности.

        Но свойство Handle возвращает корректное значение. Т.е. некое WinApi-окно все-таки есть.
          Да, некое, но не из списка стандартных виндовых, и не их потомок. :no-sad:
            Цитата Славян @
            Да, некое, но не из списка стандартных виндовых, и не их потомок. :no-sad:

            Не, это именно стандартый Win32-дескриптор.
            Вот этот код:
            ExpandedWrap disabled
              ..............
              ..............
                GetWindowInfo('Form', Self.Handle);
                GetWindowInfo('Panel2', Panel2.Handle);
                GetWindowInfo('Button3', Button3.Handle);
                GetWindowInfo('Edit1', Edit1.Handle);
                GetWindowInfo('StaticText1', StaticText1.Handle);
              ..............
              ..............
               
               
              procedure TMainForm.GetWindowInfo(AName: String; AHandle: HWND);
              var
                hFont: Winapi.Windows.HFONT;
                R: TRect;
                ProcessId, ThreadId: DWORD;
                hParentWnd: Winapi.Windows.HWND;
                FileName: array[0..2000] of Char;
              begin
                Memo1.Lines.Add('');
                hFont := Winapi.Windows.HFONT(SendMessage(AHandle, WM_GETFONT, 0, 0));
                Memo1.Lines.Add('Name: ' + AName);
                Memo1.Lines.Add('Handle: ' + IntToHex(AHandle, 8));
                Memo1.Lines.Add('Font Handle: ' + IntToHex(hFont, 8));
               
                R := Rect(-1, -1, -1, -1);
                GetWindowRect(AHandle, R);
                Memo1.Lines.Add('WindowRect: ' + IntToStr(R.Left) + ', ' + IntToStr(R.Top) + ', ' + IntToStr(R.Right) + ', ' + IntToStr(R.Bottom));
               
                ThreadId := GetWindowThreadProcessId(AHandle, ProcessId);
                Memo1.Lines.Add('ProcessId: ' + UIntToStr(ProcessId) + ', ThreadId: ' + UIntToStr(ThreadId));
               
                hParentWnd := GetParent(AHandle);
                Memo1.Lines.Add('Parent Handle: ' + IntToHex(hParentWnd, 8));
               
                FillChar(FileName, SizeOf(FileName), 0);
                GetWindowModuleFileName(AHandle, @FileName, 2000);
                Memo1.Lines.Add('Module File Name: ' + FileName);
              end;


            Выдает это:
            Цитата

            Name: Form
            Handle: 00370964
            Font Handle: 00000000
            WindowRect: 92, 56, 916, 802
            ProcessId: 1688, ThreadId: 5864
            Parent Handle: 00000000
            Module File Name: D:\temp\proba1.exe

            Name: Panel2
            Handle: 0025086A
            Font Handle: 00000000
            WindowRect: 460, 371, 645, 412
            ProcessId: 1688, ThreadId: 5864
            Parent Handle: 00370964
            Module File Name: D:\temp\proba1.exe

            Name: Button3
            Handle: 002B0862
            Font Handle: 360A11BB
            WindowRect: 468, 267, 543, 292
            ProcessId: 1688, ThreadId: 5864
            Parent Handle: 00370964
            Module File Name: D:\temp\proba1.exe

            Name: Edit1
            Handle: 00240818
            Font Handle: 360A11BB
            WindowRect: 460, 344, 581, 365
            ProcessId: 1688, ThreadId: 5864
            Parent Handle: 00370964
            Module File Name: D:\temp\proba1.exe

            Name: StaticText1
            Handle: 00210D6A
            Font Handle: 360A11BB
            WindowRect: 539, 321, 598, 338
            ProcessId: 1688, ThreadId: 5864
            Parent Handle: 00370964
            Module File Name: D:\temp\proba1.exe
              Цитата wb4 @
              Но возвращает 0. Т.е. как будто у формы установлен системный шрифт.

              Ну всё правильно:
              Цитата
              WM_GETFONT: The return value is a handle to the font used by the control, or NULL if the control is using the system font.

              А что именно смущает? Система по дефолту задаёт окну системный шрифт через GetStockObject(DEFAULT_GUI_FONT). Это тот шрифт, которым отображаются меню, текст, и т.д.
              В Delphi окну (форме) фонт задаёт система именно так (только если ты сам явно не задашь для окна какой-то другой шрифт). По этому WM_GETFONT у тебя и возвращает 0.

              Цитата wb4 @
              Т.е. некое WinApi-окно все-таки есть.

              Любое окно в Windows создаётся одинаково - регистрируется класс окна и вызывается CreateWindow. Ну а все эти т.н. "виртуальные" окна - просто прорисовка на экране (например TLabel - рисование текста ф-ей DrawText(Ex)).
                Цитата Krid @
                А что именно смущает? Система по дефолту задаёт окну системный шрифт через GetStockObject(DEFAULT_GUI_FONT). Это тот шрифт, которым отображаются меню, текст, и т.д.
                В Delphi окну (форме) фонт задаёт система именно так (только если ты сам явно не задашь для окна какой-то другой шрифт). По этому WM_GETFONT у тебя и возвращает 0.

                Смущает то, что в отладчике четко видно, что для каждого компонента производится вызов:
                ExpandedWrap disabled
                  procedure TWinControl.CreateWnd;
                   begin
                   ...........
                   ...........
                   Perform(WM_SETFONT, FFont.Handle, 1);
                   ...........
                   ...........
                   end;

                Для всех компонент одинаково.
                И TPanel рисует свой Caption своим "родным" шрифтом, но не системным.
                  А что у тебя возвращает
                  ExpandedWrap disabled
                    SendMessage(Panel1.Handle, WM_GETFONT, 0, 0);
                  ?
                  У меня - ноль. Т.е. TPanel рисует свой Caption системным шрифтом.
                    Цитата Krid @
                    Т.е. TPanel рисует свой Caption системным шрифтом.

                    Хорошо. Я поставил форме шрифт "Monotype Corsiva" размером 12. Т.е. даже близко не системный.
                    Ситуация осталась та же - форма и панель сообщают, что у них типа системный шрифт (дескриптор шрифта = 0)
                      Ну тогда конкретизируй, плз. - ты хочешь: поменять шрифт формы, не затрагивая шрифт контролов на ней. Или ты хочешь поменять шрифт формы так, чтобы шрифт контролов тоже поменялся (например, шрифт панели). Или у тебя чисто академический интерес - как можно поменять шрифт формы, чтобы он не был системным и WM_GETFONT для формы не выдавал ноль?

                      Что именно тебе нужно?

                      ЗЫ да, и обрати внимание на ф-ю TWinControl.RecreateWnd, - которая уничтожает Canvas (он же hDC, на котором всё и рисуется - и Font тоже, т.к. юзает hDC), а потом создаёт его снова - т.е. hDC и hFont сначала уничтожаются а потом сразу создаются с другими значениями hDC и hFont, чтобы потом можно рисовать на canvas (hDC), юзая заданный фонт.


                      Короче, для начала внимательно прочти матчасть.
                        Встречал объяснение Реймонда Чена - контролы windows, которые могут быть элементами диалоговых окон, должны отвечать на WM_GETFONT. А вот форма - окно верхнего уровня, и обработчика сообщения не имеет, так что срабатывает обработчик по умолчанию, возвращающий ноль.

                        Здесь и тут
                        Сообщение отредактировано: MBo -
                          Цитата Krid @
                          Ну тогда конкретизируй, плз. - ты хочешь...
                          ........

                          Мне нужно получить шрифт контрола для различных вычислений, связанных с размерами и кастомным выравниванием.
                          Желательно иметь универсальный доступ к контролу - через одну переменную, которая представляет TControl/TWinControl или дескриптор окна.

                          Добавлено
                          Цитата MBo @
                          Встречал объяснение Реймонда Чена - контролы windows, которые могут быть элементами диалоговых окон, должны отвечать на WM_GETFONT. А вот форма - окно верхнего уровня, и обработчика сообщения не имеет, так что срабатывает обработчик по умолчанию, возвращающий ноль.

                          Здесь и тут

                          А вот это интересно!
                          Спасибо!
                            Формы в Delphi создаются по правилам, по которым создаются все окна в винде, и это ты стандартными способами не изменишь.

                            Для отдельных контролов сделать это можно, но для этого нужно перехватить процедуру создание контрола.

                            Шрифт каких именно контролов ты хочешь поменять?
                              wb4
                              ExpandedWrap disabled
                                type
                                  THackControl = class(TControl);
                                //...
                                procedure TForm1.Button1Click(Sender: TObject);
                                 
                                  procedure MyProc(AControl: TControl);
                                  begin
                                    ShowMessage(THackControl(AControl).Font.Name);
                                    //THackControl(AControl).Font.Size := 12;
                                  end;
                                 
                                begin
                                  MyProc(Form1);
                                  MyProc(Panel1);
                                  MyProc(CheckBox1);
                                  MyProc(Button1);
                                end;
                                //...
                              ?
                                не сработает :no:
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0580 ]   [ 17 queries used ]   [ Generated: 29.03.24, 11:11 GMT ]