Некорректный размер окна передаваемых через секцию ресурсов.

Тема в разделе "WASM.WIN32", создана пользователем Полный 30h, 4 июн 2017.

  1. Полный 30h

    Полный 30h Member

    Публикаций:
    0
    Регистрация:
    7 дек 2016
    Сообщения:
    36
    Адрес:
    Институт Мичурина
    Доброго дня.
    Ситуация следующая. Создаю в FASM окно с помощью DialogBoxParam, с прописанными в секции ресурсов размерами. При старте размер окна не соответствует установленным цифрам (крупнее около двух раз). Соответственно при разрешении экрана по горизонтали в 1600 единиц, не могу приблизиться к этой цифре даже близко.
    При создании такого же окна при помощи функции CreateWindowEx, всё пучком. Хотя по идее, если верить интернетам, DialogBoxParam "рисует" окно так же при помощи этой же функции.
    Привожу оба исходника
    Первый, где с размером полный порядок.
    Код (ASM):
    1. format PE GUI 4.0
    2. entry Start
    3. include 'win32a.inc'
    4. section '.text' code readable executable
    5.  
    6. Start:
    7.   invoke GetModuleHandle, 0
    8.       mov [wc.hInstance], eax
    9.   invoke LoadIcon, 0, IDI_APPLICATION
    10.       mov [wc.hIcon], eax
    11.   invoke  LoadCursor, 0, IDC_ARROW                
    12.       mov [wc.hCursor], eax
    13.   invoke RegisterClass, wc                        
    14.       test eax, eax
    15.       jz error
    16.   invoke CreateWindowEx, 0, _class, _title, WS_VISIBLE + WS_DLGFRAME + WS_SYSMENU,\
    17.                          5, 50,800,200, NULL, NULL, [wc.hInstance], NULL
    18.       test eax, eax
    19.       jz error
    20.  
    21. msg_loop:
    22.   invoke GetMessage, msg, NULL, 0, 0
    23.       cmp eax, 1
    24.       jb end_loop
    25.       jne msg_loop
    26.   invoke TranslateMessage, msg
    27.   invoke DispatchMessage, msg
    28.       jmp msg_loop
    29.  
    30. error:
    31.   invoke MessageBox, NULL, _error, NULL, MB_ICONERROR + MB_OK
    32. end_loop:
    33.   invoke ExitProcess,0
    34.  
    35. proc WindowProc uses ebx esi edi, hwnd, wmsg, wparam, lparam
    36.       cmp [wmsg], WM_DESTROY
    37.       je .wmdestroy
    38.  
    39. .defwndproc:
    40.   invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam]
    41.       jmp .finish
    42.  
    43. .wmdestroy:
    44.   invoke PostQuitMessage,0
    45.       xor eax, eax
    46.  
    47. .finish:
    48.   ret
    49. endp
    50.  
    51. section '.data' data readable writeable
    52.   _class TCHAR 'FASMWIN32', 0
    53.   _title TCHAR 'Win32 program 800x200', 0
    54.   _error TCHAR 'Startup failed.', 0
    55.  
    56.   wc WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, _class
    57.   msg MSG
    58.  
    59. section '.idata' import data readable writeable
    60.  
    61.   library kernel32, 'KERNEL32.DLL',user32, 'USER32.DLL'
    62.   include 'api\kernel32.inc'
    63.   include 'api\user32.inc'
    Второй, где окно растаскивает по монитору, как депутатскую рожу к концу избирательного срока
    Код (Text):
    1. format PE GUI 4.0
    2. entry Start
    3. include 'win32a.inc'
    4. section '.text' code readable executable
    5.  
    6. Start:
    7.   invoke GetModuleHandle, 0
    8.       mov [wc.hInstance], eax
    9.   invoke LoadIcon, 0, IDI_APPLICATION
    10.       mov [wc.hIcon], eax
    11.   invoke  LoadCursor, 0, IDC_ARROW                
    12.       mov [wc.hCursor], eax
    13.   invoke RegisterClass, wc                        
    14.       test eax, eax
    15.       jz error
    16.   invoke  DialogBoxParam,[wc.hInstance],DWIN1,0,WindowProc,0    ;
    17.       test eax, eax
    18.       jz error
    19.  
    20. msg_loop:
    21.   invoke GetMessage, msg, NULL, 0, 0
    22.       cmp eax, 1
    23.       jb end_loop
    24.       jne msg_loop
    25.   invoke TranslateMessage, msg
    26.   invoke DispatchMessage, msg
    27.       jmp msg_loop                                                                                
    28.        
    29. error:
    30.   invoke MessageBox, NULL, _error, NULL, MB_ICONERROR + MB_OK
    31. end_loop:
    32.   invoke ExitProcess,0
    33.  
    34.  
    35. proc WindowProc uses ebx esi edi, hwnd, wmsg, wparam, lparam
    36.       cmp [wmsg], WM_DESTROY
    37.       je .wmdestroy
    38.    
    39. .defwndproc:
    40.   invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam]
    41.       jmp .finish
    42.  
    43. .wmdestroy:
    44.   invoke PostQuitMessage,0
    45.       xor eax, eax
    46.  
    47. .finish:
    48.   ret
    49. endp
    50.  
    51. section '.data' data readable writeable
    52.   _class TCHAR 'FASMWIN32', 0
    53.   _title TCHAR 'Win32 resource', 0
    54.   _error TCHAR 'Startup failed.', 0
    55.      DWIN1=100  
    56.    
    57.   wc WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, _class
    58.   msg MSG
    59. section '.rsrc' resource data readable  ;
    60. directory RT_DIALOG,dialog1
    61. resource dialog1,DWIN1,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration1
    62.   dialog demonstration1,'Win32 resource 800x200',5, 50,800,200,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME,0,0,'Arial',10   ; Окно                            
    63.   enddialog
    64.  
    65. section '.idata' import data readable writeable
    66.   library kernel32, 'KERNEL32.DLL',user32, 'USER32.DLL'
    67.   include 'api\kernel32.inc'
    68.   include 'api\user32.inc'
    Что я делаю не так?

    Для наглядности скрин безобразия.
     

    Вложения:

  2. vadimych

    vadimych Member

    Публикаций:
    0
    Регистрация:
    20 июн 2011
    Сообщения:
    55
    Полный 30h, попробуй уменьшить размер шрифта в ресурсах.
     
    Коцит и Полный 30h нравится это.
  3. Полный 30h

    Полный 30h Member

    Публикаций:
    0
    Регистрация:
    7 дек 2016
    Сообщения:
    36
    Адрес:
    Институт Мичурина
    Вадимыч, спасибо тебе огромное! несколько часов крутил вертел, как то привык сам до всего доходить. Но вот только ума не приложу, как одно с другим может быть на столько связано. Ведь косячина-бажина по большому счету. Десятый шрифт так окно разносит, к тому же пустое.
    Ещё раз большое спасибо за подсказку и оперативность.
     
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Полный 30h,
    это проблема не только FASM. В MASM всё тоже самое. Верхний диалог создан через DialogBoxParam и имеет размер 400х100, нижнее окошко создано через RegisterClassEx/CreateWindowEx с размерами 800х200
    [​IMG]
    просто принимаю как должное коэффициент 1:2, размер шрифта в диалоге не указан, попробовал указать минимальный размер шрифта 1, при этом диалогу 400х100 соответствует окошко 610х200. Жалко kero здесь редко бывает, наверняка подсказал бы в чем дело...
     

    Вложения:

    • 00.png
      00.png
      Размер файла:
      106,7 КБ
      Просмотров:
      1.000
    Полный 30h нравится это.
  5. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    861
    Потому что размеры задаются не в пикселях.
    По теме.
     
    Коцит и Полный 30h нравится это.
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
  7. Полный 30h

    Полный 30h Member

    Публикаций:
    0
    Регистрация:
    7 дек 2016
    Сообщения:
    36
    Адрес:
    Институт Мичурина
    Thetrik, спасибо за ссылку и цитату. Попробую разобраться, у меня английский со словарём, общий смысл правда кажется уловил. Если справлюсь, тут выложу.

    Mikl___, буду в ссылку Техника вникать. Метод научного тыка через шрифт от Вадимыча конечно имеет право на жизнь, и как костыль годен, но столько времени убил пытаясь самостоятельно дойти до решения, что хочется уже научной красоты, а не совы на глобусе.
     
  8. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Полный 30h,
    там вникать не во что, размер окон измеряется в пикселах, размер диалогов согласно формуле:
    horz pixels == 2 * horz dialog units * (average char width of dialog font / average char width of system font)
    vert pixels == 2 * vert dialog units * (average char height of dialog font / average char height of system font)
    двойка умноженная на единицу диалога умноженное на соотношение указанного шрифта к системному шрифту
     
    Коцит и Полный 30h нравится это.
  9. Полный 30h

    Полный 30h Member

    Публикаций:
    0
    Регистрация:
    7 дек 2016
    Сообщения:
    36
    Адрес:
    Институт Мичурина
    Mikl___, да, насчёт двойки я уже разобрался. Осталось только разобраться что такое единица диалога и откуда брать соотношения указанного шрифта и системного. чисто интуитивно я конечно понимаю, что не сложнее чем по воротнику футболки определить размер рукава. Не программист я ни разу, даже близко не являюсь, делай скидку.
     
  10. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Если диалог со стандартным системным шрифтом, что base units получаем через GetDialogBaseUnits(), иначе base units равны средней ширине символа конкретного шрифта и высоте символа (GetTextMetrics()).

    Перевод из размеров с ресурсном шаблоне в оконные размеры:
    Код (C):
    1.  
    2. pixelX = MulDiv(templateUnitX, baseUnitX, 4);
    3. pixelY = MulDiv(templateUnitY, baseUnitY, 8);
    4.  
     
    Коцит, Mikl___ и Полный 30h нравится это.
  11. Полный 30h

    Полный 30h Member

    Публикаций:
    0
    Регистрация:
    7 дек 2016
    Сообщения:
    36
    Адрес:
    Институт Мичурина
    Я пожалуй возьму тайм аут по данному вопросу. Как то совсем мозг заколодило с этими BaseUnits. Я так понял для начала нужно получить эти самые единицы Units при помощи GetDialogBaseUnits. Вернёт она их в EAX. А после, использовать функцию MapDialogRect. Которая преобразует мне эти Units и т.д. и т.п. Вот ведь только незадача, приходит значение BaseUnits в четырехбайтовый регистр, а забирается для перерасчета аж из 16 байтовой структуры RECT. И это ещё дело не дошло до перерисовки окна, если я всё это правильно понимаю.
    Короче. Заманчивая по началу секция ресурсов, искушавшая минимумом писанины по поводу обустройства контролов, потеряла всяческий интерес. И на данном этапе знакомства с темой, как мне кажется, создание контролов через
    CreateWindowEx кажется мне более логичным занятием.
    Ещё раз хочу поблагодарить всех откликнувшихся за массу полезной информации в целом и моральную поддержку в частности. Если кто то захочет ради спортивного интереса продолжить педалить тему, буду только рад.


     
    Коцит нравится это.