Доброго дня. Ситуация следующая. Создаю в FASM окно с помощью DialogBoxParam, с прописанными в секции ресурсов размерами. При старте размер окна не соответствует установленным цифрам (крупнее около двух раз). Соответственно при разрешении экрана по горизонтали в 1600 единиц, не могу приблизиться к этой цифре даже близко. При создании такого же окна при помощи функции CreateWindowEx, всё пучком. Хотя по идее, если верить интернетам, DialogBoxParam "рисует" окно так же при помощи этой же функции. Привожу оба исходника Первый, где с размером полный порядок. Код (ASM): format PE GUI 4.0 entry Start include 'win32a.inc' section '.text' code readable executable Start: invoke GetModuleHandle, 0 mov [wc.hInstance], eax invoke LoadIcon, 0, IDI_APPLICATION mov [wc.hIcon], eax invoke LoadCursor, 0, IDC_ARROW mov [wc.hCursor], eax invoke RegisterClass, wc test eax, eax jz error invoke CreateWindowEx, 0, _class, _title, WS_VISIBLE + WS_DLGFRAME + WS_SYSMENU,\ 5, 50,800,200, NULL, NULL, [wc.hInstance], NULL test eax, eax jz error msg_loop: invoke GetMessage, msg, NULL, 0, 0 cmp eax, 1 jb end_loop jne msg_loop invoke TranslateMessage, msg invoke DispatchMessage, msg jmp msg_loop error: invoke MessageBox, NULL, _error, NULL, MB_ICONERROR + MB_OK end_loop: invoke ExitProcess,0 proc WindowProc uses ebx esi edi, hwnd, wmsg, wparam, lparam cmp [wmsg], WM_DESTROY je .wmdestroy .defwndproc: invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam] jmp .finish .wmdestroy: invoke PostQuitMessage,0 xor eax, eax .finish: ret endp section '.data' data readable writeable _class TCHAR 'FASMWIN32', 0 _title TCHAR 'Win32 program 800x200', 0 _error TCHAR 'Startup failed.', 0 wc WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, _class msg MSG section '.idata' import data readable writeable library kernel32, 'KERNEL32.DLL',user32, 'USER32.DLL' include 'api\kernel32.inc' include 'api\user32.inc' Второй, где окно растаскивает по монитору, как депутатскую рожу к концу избирательного срока Код (Text): format PE GUI 4.0 entry Start include 'win32a.inc' section '.text' code readable executable Start: invoke GetModuleHandle, 0 mov [wc.hInstance], eax invoke LoadIcon, 0, IDI_APPLICATION mov [wc.hIcon], eax invoke LoadCursor, 0, IDC_ARROW mov [wc.hCursor], eax invoke RegisterClass, wc test eax, eax jz error invoke DialogBoxParam,[wc.hInstance],DWIN1,0,WindowProc,0 ; test eax, eax jz error msg_loop: invoke GetMessage, msg, NULL, 0, 0 cmp eax, 1 jb end_loop jne msg_loop invoke TranslateMessage, msg invoke DispatchMessage, msg jmp msg_loop error: invoke MessageBox, NULL, _error, NULL, MB_ICONERROR + MB_OK end_loop: invoke ExitProcess,0 proc WindowProc uses ebx esi edi, hwnd, wmsg, wparam, lparam cmp [wmsg], WM_DESTROY je .wmdestroy .defwndproc: invoke DefWindowProc, [hwnd], [wmsg], [wparam], [lparam] jmp .finish .wmdestroy: invoke PostQuitMessage,0 xor eax, eax .finish: ret endp section '.data' data readable writeable _class TCHAR 'FASMWIN32', 0 _title TCHAR 'Win32 resource', 0 _error TCHAR 'Startup failed.', 0 DWIN1=100 wc WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, _class msg MSG section '.rsrc' resource data readable ; directory RT_DIALOG,dialog1 resource dialog1,DWIN1,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration1 dialog demonstration1,'Win32 resource 800x200',5, 50,800,200,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME,0,0,'Arial',10 ; Окно enddialog section '.idata' import data readable writeable library kernel32, 'KERNEL32.DLL',user32, 'USER32.DLL' include 'api\kernel32.inc' include 'api\user32.inc' Что я делаю не так? Для наглядности скрин безобразия.
Вадимыч, спасибо тебе огромное! несколько часов крутил вертел, как то привык сам до всего доходить. Но вот только ума не приложу, как одно с другим может быть на столько связано. Ведь косячина-бажина по большому счету. Десятый шрифт так окно разносит, к тому же пустое. Ещё раз большое спасибо за подсказку и оперативность.
Полный 30h, это проблема не только FASM. В MASM всё тоже самое. Верхний диалог создан через DialogBoxParam и имеет размер 400х100, нижнее окошко создано через RegisterClassEx/CreateWindowEx с размерами 800х200 просто принимаю как должное коэффициент 1:2, размер шрифта в диалоге не указан, попробовал указать минимальный размер шрифта 1, при этом диалогу 400х100 соответствует окошко 610х200. Жалко kero здесь редко бывает, наверняка подсказал бы в чем дело...
Thetrik, спасибо за ссылку и цитату. Попробую разобраться, у меня английский со словарём, общий смысл правда кажется уловил. Если справлюсь, тут выложу. Mikl___, буду в ссылку Техника вникать. Метод научного тыка через шрифт от Вадимыча конечно имеет право на жизнь, и как костыль годен, но столько времени убил пытаясь самостоятельно дойти до решения, что хочется уже научной красоты, а не совы на глобусе.
Полный 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) двойка умноженная на единицу диалога умноженное на соотношение указанного шрифта к системному шрифту
Mikl___, да, насчёт двойки я уже разобрался. Осталось только разобраться что такое единица диалога и откуда брать соотношения указанного шрифта и системного. чисто интуитивно я конечно понимаю, что не сложнее чем по воротнику футболки определить размер рукава. Не программист я ни разу, даже близко не являюсь, делай скидку.
Если диалог со стандартным системным шрифтом, что base units получаем через GetDialogBaseUnits(), иначе base units равны средней ширине символа конкретного шрифта и высоте символа (GetTextMetrics()). Перевод из размеров с ресурсном шаблоне в оконные размеры: Код (C): pixelX = MulDiv(templateUnitX, baseUnitX, 4); pixelY = MulDiv(templateUnitY, baseUnitY, 8);
Я пожалуй возьму тайм аут по данному вопросу. Как то совсем мозг заколодило с этими BaseUnits. Я так понял для начала нужно получить эти самые единицы Units при помощи GetDialogBaseUnits. Вернёт она их в EAX. А после, использовать функцию MapDialogRect. Которая преобразует мне эти Units и т.д. и т.п. Вот ведь только незадача, приходит значение BaseUnits в четырехбайтовый регистр, а забирается для перерасчета аж из 16 байтовой структуры RECT. И это ещё дело не дошло до перерисовки окна, если я всё это правильно понимаю. Короче. Заманчивая по началу секция ресурсов, искушавшая минимумом писанины по поводу обустройства контролов, потеряла всяческий интерес. И на данном этапе знакомства с темой, как мне кажется, создание контролов через CreateWindowEx кажется мне более логичным занятием. Ещё раз хочу поблагодарить всех откликнувшихся за массу полезной информации в целом и моральную поддержку в частности. Если кто то захочет ради спортивного интереса продолжить педалить тему, буду только рад.