Проблема с изменением шрифта в Блокноте

Тема в разделе "WASM.BEGINNERS", создана пользователем YaMolekula, 7 ноя 2010.

  1. YaMolekula

    YaMolekula New Member

    Публикаций:
    0
    Регистрация:
    10 ноя 2009
    Сообщения:
    20
    Доброго времени суток! Вот написал небольшую программу, которая должна менять шрифт в открытом окне блокнота:
    Код (Text):
    1. format PE GUI 4.0
    2. include 'win32ax.inc'
    3.  
    4. .data  
    5.         notepad db 'notepad', 0
    6.         _font db 'Courier',0
    7. .code
    8.         start:
    9.         invoke FindWindow, notepad, 0
    10.         invoke SendMessage, eax, WM_SETFONT, _font, 1
    11.         invoke ExitProcess, 0
    12. .end start
    Программа не работает. Думаю, что неправильно задал шрифт, но не знаю как его правиьно задать. Как все же программно поменять шрифт?
    P.S. Странно, но у каждого файла свой шрифт, я думал что это настройка самого приложения.
     
  2. emptyHook

    emptyHook New Member

    Публикаций:
    0
    Регистрация:
    9 сен 2010
    Сообщения:
    63
    вообще то, насколько я помню, передавать надо хэндл на FONT, а не название шрифта

    иначе юзается системный
     
  3. YaMolekula

    YaMolekula New Member

    Публикаций:
    0
    Регистрация:
    10 ноя 2009
    Сообщения:
    20
    Кажется, у меня скоро возникнет новый вопрос.
    Ухты, а где его можно взять?
     
  4. gazlan

    gazlan Member

    Публикаций:
    0
    Регистрация:
    22 май 2005
    Сообщения:
    414
    Обрывок на С. Последовательность та же.

    Код (Text):
    1.    
    2.    LOGFONT     LF;
    3.    
    4.    memset(&LF,0,sizeof(LOGFONT));            // zero out structure
    5.    
    6.    LF.lfHeight = 16;                         // request a 16-pixel-height font
    7.    strcpy(LF.lfFaceName,"Courier New");      // request a face name
    8.    
    9.    VERIFY(_Font.CreateFontIndirect(&LF));    // create the font
    10.  
    11.    m_List.SetFont(&_Font,FALSE);
     
  5. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    gazlan
    Это C++ :)
     
  6. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    см. архив :)
     
  7. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    KeSqueerинформативный пост кэп
     
  8. emptyHook

    emptyHook New Member

    Публикаций:
    0
    Регистрация:
    9 сен 2010
    Сообщения:
    63
    http://msdn.microsoft.com/en-us/library/dd183499(VS.85).aspx

    учимся пользоваться поиском =)
     
  9. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    emptyHook,
    Код (Text):
    1. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    2. {
    3. ...
    4.     switch (message)
    5.     {
    6.     case WM_PAINT:
    7. ...
    8.     CreateFont
    9. ...и так пару раз; веселый паровоз, если каждую прорисовку так делать
     
  10. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    punxer
    Чуть более информативнее Вашего
     
  11. gazlan

    gazlan Member

    Публикаций:
    0
    Регистрация:
    22 май 2005
    Сообщения:
    414
    MFC, если вы настаиваете на деталях. Но в данном случае, это неважно. Последовательность та же.

    Вот, для примера, кусочек на чистом API:

    Код (Text):
    1. LRESULT CALLBACK OwnerDraw_Callback
    2. (
    3.    HWND           hWnd,
    4.    UINT           uiMsg,
    5.    WPARAM         wParam,
    6.    LPARAM         lParam
    7. )
    8. {
    9.    switch (uiMsg)
    10.    {      
    11.       case WM_SETCURSOR:
    12.       {
    13. //
    14.       }    
    15.       case WM_LBUTTONDOWN:
    16.       {
    17. //
    18.       }
    19.       case WM_LBUTTONUP:
    20.       {
    21. //
    22.       }
    23.       case WM_PAINT:
    24.       {
    25.          PAINTSTRUCT       ps;
    26.  
    27.          HDC      dc = BeginPaint(hWnd,&ps);
    28.  
    29.          // Create underlined font
    30.          LOGFONT  lf;
    31.          HFONT    hFont = (HFONT)SendMessage(GetParent(hWnd),WM_GETFONT,0,0);
    32.          
    33.          GetObject(hFont,sizeof(lf),&lf);
    34.          
    35.          lf.lfUnderline = TRUE;
    36.          
    37.          hFont = CreateFontIndirect(&lf);
    38.          
    39.          // Get text to draw
    40.          int      len = GetWindowTextLength(hWnd);
    41.          
    42.          char     str[MAX_PATH];
    43.  
    44.          len = GetWindowText(hWnd,str,len + 1);
    45.          
    46.          // Prepare DC
    47.          COLORREF    cr = SetTextColor(dc,RGB(0,0,255));
    48.          HGDIOBJ     hOldFont = SelectObject(dc,hFont);
    49.          
    50.          int bk = SetBkMode(dc,TRANSPARENT);
    51.          
    52.          // Draw
    53.          RECT     rc;
    54.          
    55.          GetClientRect(hWnd,&rc);
    56.          
    57.          DrawText(dc,str,len,&rc,DT_SINGLELINE | DT_NOPREFIX | DT_CENTER);
    58.          
    59.          // Unprepare DC
    60.          SelectObject(dc, hOldFont);
    61.          SetBkMode(dc, bk);
    62.          SetTextColor(dc, cr);
    63.          DeleteObject(hFont);
    64.          
    65.          // Finish
    66.          EndPaint(hWnd,&ps);
    67.          return 0;
    68.       }
    69.    }
    70.  
    71.    return DefWindowProc(hWnd,uiMsg,wParam,lParam);
    72. }
     
  12. YaMolekula

    YaMolekula New Member

    Публикаций:
    0
    Регистрация:
    10 ноя 2009
    Сообщения:
    20
    Спасибо большое, дело заметно продвинулось. Особенно громаднейшее спасибо edemko за информативный исходник: очень помогло рассмотрение того, как это всё реализуется на практике. Программа находит текстовое поле, и даж пишет туда текст. Но проблема в том, что шрифт по какой-то причине не поменялся.
    Код (Text):
    1. format PE GUI 4.0
    2. include 'win32ax.inc'
    3.  
    4. .data  
    5.         notepad db 'notepad', 0
    6.         hw rd 4                        ;хэндл верхнего окна
    7.         hchild rd 4                    ;хэндл дочернего окна
    8.         hFont rd 4                    ;шрифт
    9.         ClassName rd 1              ;здесь храним имя класса дочернего окна
    10.  
    11.  
    12.  lf LOGFONT \
    13.     12,7,\                                                   ;lfHeight & lfWidth
    14.     0,0,\                                                    ;lfEscapement(наклон отн. Х в 10х градуса) & lfOrientation
    15.     FW_NORMAL,0,0,0,\                                        ;lfWeight & lfItalic & lfUnderline & lfStrikeOut
    16.     RUSSIAN_CHARSET,\                                        ;lfCharSet
    17.     OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\ ;lfOutPrecision & lfClipPrecision & lfQuality
    18.     FF_MODERN+FIXED_PITCH,\              ;lpPitchAndFamily ;FIXED_PITCH=моноширинный=красивосорцен Ж)
    19.     'lucida console'                                            ;lfFaceName
    20.  
    21. .code
    22.         start:
    23.         invoke ShellExecute,NULL,NULL,'notepad.exe',NULL,NULL,SW_SHOW
    24.         invoke MessageBox,HWND_DESKTOP,"Запуск Блокнота",0,0
    25.         invoke  CreateFontIndirectA,lf ;создание шрифта
    26.         mov [hFont],eax
    27.         invoke FindWindow, notepad, 0
    28.         mov [hw],eax
    29.         invoke  EnumChildWindows,[hw],EnumChildProc, NULL
    30.         invoke SendMessage,[hchild],WM_SETTEXT,100,"аБвГд"
    31.         invoke MessageBox,HWND_DESKTOP,"Теперь поменяем шрифт (в любом случае, последние две буквы поменяют регистр)",0,0
    32.         invoke SendDlgItemMessageA,hchild,3,WM_SETFONT,[hFont],TRUE ;FALSE
    33.         invoke SendMessage,hchild,3,WM_SETFONT,[hFont],TRUE         ;FALSE
    34. ;какая-то из двух предыдущих должна заработать
    35.         invoke SendMessage,[hchild],WM_SETTEXT,100,"аБвгД"
    36.         invoke ExitProcess, 0
    37.  
    38. proc    EnumChildProc hwchild,NULL
    39.         push ebx esi edi
    40.         invoke GetClassName, [hwchild],ClassName,5     ;Ищем по классу
    41.         cmp [ClassName],"Edit"     ;сравниваем с искомым
    42.         je equi
    43. finish:
    44.         pop  edi esi ebx
    45.         ret
    46. equi:
    47.         mov eax,0
    48.         invoke  MessageBox,HWND_DESKTOP,"Найден класс Edit",0,0
    49.         mov eax,[hwchild]
    50.         mov [hchild],eax
    51.         jmp finish
    52. endp
    53. .end start
    Я там ввёл сразу две функции изменения шрифта, чтоб наверняка.
     
  13. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    В отличие от WM_SETTEXT, WM_SETFONT - не транзитивный: блокнот будет искать посланные ему шрифт где-то в своем адресном пространстве.

    Код (Text):
    1. format pe gui 4.0
    2. include 'win32ax.inc'
    3.  
    4.  
    5. section '' code executable import readable writable
    6.   library gdi32,'gdi32.dll',\
    7.           kernel32,'kernel32.dll',\
    8.           user32,'user32.dll'
    9.  
    10.   include 'api\gdi32.inc'
    11.   include 'api\kernel32.inc'
    12.   include 'api\user32.inc'
    13.  
    14.  
    15.   lf LOGFONT \
    16.      12,7,\                                                   ;lfHeight & lfWidth
    17.      0,0,\                                                    ;lfEscapement(наклон отн. Х в 10х градуса) & lfOrientation
    18.      FW_NORMAL,0,0,0,\                                        ;lfWeight & lfItalic & lfUnderline & lfStrikeOut
    19.      RUSSIAN_CHARSET,\                                        ;lfCharSet
    20.      OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\ ;lfOutPrecision & lfClipPrecision & lfQuality
    21.      FF_MODERN+FIXED_PITCH,\                                  ;lpPitchAndFamily ;FIXED_PITCH=моноширинный=красивосорцен Ж)
    22.      'courier new'                                         ;lfFaceName
    23.  
    24.  
    25.   hw rd 1
    26.   hf rd 1
    27.  
    28.   entry $
    29.      invoke  FindWindowExA,<invoke  FindWindowA,'notepad',0>,0,'edit',0
    30.      mov     [hw],eax
    31.      invoke  SendMessageA,eax,WM_SETTEXT,0,'fedc''ba98''7654''3210'
    32.  
    33.      invoke  CreateFontIndirectA,lf
    34.      mov     [hf],eax
    35.      invoke  SendMessageA,[hw],WM_SETFONT,eax,TRUE
    36.  
    37.      invoke  ExitProcess,0
     
  14. YaMolekula

    YaMolekula New Member

    Публикаций:
    0
    Регистрация:
    10 ноя 2009
    Сообщения:
    20
    Снова одна проблема: я создаю второй шрифт (такой же, только подчёркнут), но шрифт остаётся таким же, не понимаю в чём может быть дело.
    Код (Text):
    1. format pe gui 4.0
    2. include 'win32ax.inc'
    3.  
    4.  
    5. section '' code executable import readable writable
    6.   library gdi32,'gdi32.dll',\
    7.       kernel32,'kernel32.dll',\
    8.       user32,'user32.dll'
    9.  
    10.   include 'api\gdi32.inc'
    11.   include 'api\kernel32.inc'
    12.   include 'api\user32.inc'
    13.  
    14.  
    15. lf1 LOGFONT \
    16.      12,7,\                           ;lfHeight & lfWidth
    17.      0,0,\                            ;lfEscapement(наклон отн. Х в 10х градуса) & lfOrientation
    18.      FW_NORMAL,0,0,0,\                        ;lfWeight & lfItalic & lfUnderline & lfStrikeOut
    19.      RUSSIAN_CHARSET,\                        ;lfCharSet
    20.      OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\ ;lfOutPrecision & lfClipPrecision & lfQuality
    21.      FF_MODERN+FIXED_PITCH,\                      ;lpPitchAndFamily ;FIXED_PITCH=моноширинный=красивосорцен Ж)
    22.      'courier new'                     ;lfFaceName
    23.  
    24. lf2 LOGFONT \
    25.      12,7,\                           ;lfHeight & lfWidth
    26.      0,0,\                            ;lfEscapement(наклон отн. Х в 10х градуса) & lfOrientation
    27.      FW_NORMAL,0,TRUE,0,\                    ;lfWeight & lfItalic & lfUnderline & lfStrikeOut
    28.      RUSSIAN_CHARSET,\                        ;lfCharSet
    29.      OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\ ;lfOutPrecision & lfClipPrecision & lfQuality
    30.      FF_MODERN+FIXED_PITCH,\                      ;lpPitchAndFamily ;FIXED_PITCH=моноширинный=красивосорцен Ж)
    31.      'courier new'
    32.  
    33.   hw rd 1
    34.   hf rd 1
    35.  
    36.  
    37.   entry $
    38.  
    39.  
    40.      invoke MessageBoxA,HWND_DESKTOP,"Шрифт по настройкам меню",0,0
    41.  
    42.      invoke  FindWindowExA,<invoke  FindWindowA,'notepad',0>,0,'edit',0
    43.      mov     [hw],eax
    44.      invoke  SendMessageA,[hw],WM_SETTEXT,0,'fedc''ba98''7654''3210'
    45.  
    46.      invoke MessageBox,HWND_DESKTOP,"Изменённый шрифт(первый вариант)",0,0
    47.  
    48.      invoke  CreateFontIndirectA,lf1
    49.      mov     [hf],eax
    50.      invoke  SendMessageA,[hw],WM_SETFONT,eax,TRUE
    51.  
    52.      invoke MessageBox,HWND_DESKTOP,"Изменённый шрифт(второй вариант)",0,0
    53.  
    54.      invoke  CreateFontIndirectA,lf2
    55.      mov     [hf],eax
    56.      invoke  SendMessageA,[hw],WM_SETFONT,0,TRUE
    57.  
    58.      invoke  ExitProcess,0
     
  15. yentb

    yentb New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2010
    Сообщения:
    1
  16. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    WM_SETFONT действует в рамках одного приложения.

    ВСЕ НИЖЕ К ЭТОЙ ТЕМЕ ОСОБОГО ОТНОШЕНИЯ НЕ ИМЕЕТ


    :)
    Нашел медведь здоровую бочку меда.
    Пошол домой за повозкой, на бочке написал "бочка пуста и меда в ней нет".
    Вернулся и видит надпись: "ежик мед не трогал".
    :)

    Странно, но notepad.exe на прорисовках создает заново шрифт.
    Глупо.

    Ниже рисунок, как блокнот меняет шрифт после ШрифтДиалога(ChoseFontW).
    А перед этим видим такую строчку:
    Код (Text):
    1. CPU Disasm
    2. Address    Hex dump                    Command                                        Comments
    3. 01003052   |.  BF 20AB0001             mov     edi,offset notepad.0100AB20
    [​IMG]
     
  17. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Не совсем. Послать-то его можно, но в контексте устройства для окна-приёмника будет выбран "System, 8pt" (шрифт по умолчанию). Кстати, с термином «транзитивность» вольничать — некорректно. :derisive:
     
  18. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    Все дело в букве "з", я так и знал.