Обучающая программа "Окна" в windows не компилируется - Assembler

Узнай цену своей работы

Формулировка задачи:

Assembling: D:\MYPROG\Firstprogram\window.asm D:\MYPROG\Firstprogram\window.asm(29) : error A2136: too many arguments to INVOKE D:\MYPROG\Firstprogram\window.asm(33) : error A2111: conflicting parameter definition D:\MYPROG\Firstprogram\window.asm(100) : fatal error A1010: unmatched block nesting : WndProc Прога
.486
.model flat, stdcall
option casemap:none
 
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\gdi32.inc
 
WinMain PROTO STDCALL :DWORD, :DWORD, :DWORD ;Теперь зарегистрируем класс в процедуре WinMain. В этой процедуре находится инициализация окна.
WndProc PROTO STDCALL   :DWORD, :DWORD, :DWORD, :DWORD

.data?
 
hInstance dd ?
ClassName db "FirstWindowClass",0
AppName         db      "FirstWindow",0

.code
start:
 
invoke GetModuleHandle, NULL
mov hInstance, eax ; Этот код получит хэндл модуля функцией getmodulehandle, поместите хэндл в переменную hInstance.
invoke WinMain, hInstance, NULL, NULL, SW_SHOWNORMAL  ;error A2136: too many arguments to INVOKE
invoke  ExitProcess, NULL

WinMain proc hInst:DWORD, hPrevInst:DWORD, CmdLine:DWORD, CmdShow:DWORD   ;error A2111: conflicting parameter definition
LOCAL wc:WNDCLASSEX
LOCAL hwnd:DWORD 
LOCAL msg:MSG
;Вы не обязаны объявлять функцию winmain. На самом деле, вы совершенно свободны в этом отношении.
;hInst это описатель экземпляра (= хэндл модуля),
;hPrevInst это хэндл предыдущего экземпляра программы. Под win32 нет такого понятия, как предыдущий экземпляр программы. 
;Каждая программа одна единственная в своем адресном пространстве, поэтому значение этой переменной всегда 0. Это пережиток времен Win16, когда все экземпляры программы запускались в одном и том-же адресном пространстве, и экземпляр мог узнать, были ли запущены еще копии этой программы. Под Win16, если это значение равно NULL, тогда этот экземпляр является первым.
;CmdLine указатель на коммандную строку.
;CmdShow это флаг, который определяет, как должно быть показанно окно. 
 
mov  wc.cbSize,SIZEOF WNDCLASSEX ;cbSize Размер структуры WNDCLASSEX в байтах. Вы можете получить этот размер с помощью оператора SIZEOF:
mov  wc.style, CS_HREDRAW or CS_VREDRAW ;UINT style структуры WNDCLASSEX   класса установлен в "CS_HREDRAW or CS_VREDRAW", затем установлен указатель оконной процедуры.
mov  wc.lpfnWndProc, OFFSET WndProc ;структуры WNDCLASSEX Указатель на процедуру окна (об этом я расскажу ниже)
mov  wc.cbClsExtra,NULL ;структуры WNDCLASSEX Количество дополнительных байтов, которые нужно зарезервировать (они будут следовать за самой структурой). 
mov  wc.cbWndExtra,NULL ;структуры WNDCLASSEX Количество дополнительных батов, которые нужно зарезервировать (они будут следовать за window instance).  
push hInst;  это описатель экземпляра (= хэндл модуля)
pop  wc.hInstance ;структуры WNDCLASSEX Хэндл вашей программы. Вы можете получить это хэндл функцией GetModuleHandle. 
mov  wc.hbrBackground,COLOR_WINDOW ; HBRUSH hbrBackground структуры WNDCLASSEX  Хэндл кисти для закрашивания фона, или один из стандартных, таких как COLOR_WINDOW, COLOR_BTNFACE , COLOR_BACKGROUND. 
mov  wc.lpszMenuName,NULL ; LPCTSTR lpszMenuName структуры WNDCLASSEX  Указатель на строку с нулевым символом в конце, которая определяет имя ресурса меню класса. Это также может быть ID ресурса. 
mov  wc.lpszClassName,OFFSET ClassName ;LPCTSTR lpszClassName структуры WNDCLASSEX  Указатель на строку с нулевым символом в конце, которая определяет имя класса для окон.
invoke LoadIcon,NULL,IDI_APPLICATION ; Окну нужен зачек (иконка), а для этого нам нужен хэндл иконки, мы используем LoadIcon,
 ;чтобы загрузить значок (иконку) и получать ее хэндл.
 ;LoadIcon имеет два параметра: hInstance, и lpIconName. hInstance - хэндл модуля, чей исполняемый файл содержит значок.
 ;LpIconName - указатель на строку, которая является названием ресурса значка или ID ресурса.
 ;Если вы используете NULL как hInstance, то вы можете выбрать из некоторых стандартных значков. 
 ;(что мы здесь и делаем, потому что у нас нет ресурса значка). HIconSm - маленький значок, вы можете использовать тот же
 ;хэндл и для него.
mov  wc.hIcon, eax ;структуры WNDCLASSEX Хэндл иконки. Получите его функцией LoadIcon.
mov  wc.hIconSm, eax ;HICON hIconSm структуры WNDCLASSEX Хэнд маленькой иконки.
invoke LoadCursor,NULL,IDC_ARROW ;оже самое и для курсора, только NULL в hInstance, и стандартный тип курсора: IDC_ARROW, стандартная стрелка windows.
mov  wc.hCursor,eax ;структуры WNDCLASSEX Хэндл курсора. Получите его функцией LoadCursor. 
invoke RegisterClassEx, ADDR wc    ;Класс окна в вашей программе регистрируется с помощью функции 'RegisterClassEx'
 
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\  
           WS_OVERLAPPEDWINDOW-WS_SIZEBOX-WS_MAXIMIZEBOX,CW_USEDEFAULT,\ ;стиль - WS_OVERLAPPEDWINDOW, который создает перекрытое окно с заголовком, системным меню, с изменяемым размером и кнопками свернуть/развернуть.
           CW_USEDEFAULT,400,300,NULL,NULL,\ ;CW_USEDEFAULT как x и y позиция, установит окну заданные по умолчанию позиции для новых окон. Размер окна - 400x300 пикселей.
           hInst,NULL
    mov   hwnd,eax ;Возвращаемое значение функции это хэндл окна, HWND, который сохраняется в локальной переменной hwnd. 
    invoke ShowWindow, hwnd,SW_SHOWNORMAL ; Затем окно выводится на экран функцией ShowWindow.
    invoke UpdateWindow, hwnd ;Функция UpdateWindow гарантирует, что окно будет выведено.
    .WHILE TRUE
        invoke GetMessage, ADDR msg,NULL,0,0
        .BREAK .IF (!eax)
                invoke TranslateMessage, ADDR msg
                invoke DispatchMessage, ADDR msg
 
    .ENDW
    mov     eax,msg.wParam
 
ret
WinMain endp
 
WndProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD ;12.7 - Оконная процедура. Оконная процедура должна всегда выглядеть следующим образом:
mov eax, uMsg ;Оконная процедура должна всегда иметь 4 параметра: hWnd содержит хэндл окна; uMsg это сообщение; wParam это первый параметр для сообщения; lParam второй параметр для сообщения      
.IF eax==WM_CREATE
    invoke  MessageBox, NULL, ADDR AppName, ADDR AppName, NULL
.ELSEIF eax==WM_DESTROY
    invoke PostQuitMessage, NULL
.ELSE
    invoke DefWindowProc, hWnd, uMsg, wParam, lParam;  Сообщения, которые не обрабатывает окно, должны быть переданы функции DefWindowProc, которая занимается их обработкой. 
.ENDIF
ret

end start
Если можно давайте разбирём пошагово invoke. Что оно делает первый шаг, второй шаг.. -в точности.

Решение задачи: «Обучающая программа "Окна" в windows не компилируется»

textual
Листинг программы
WinMain PROTO STDCALL :DWORD, :DWORD, :DWORD

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.25 из 5
Похожие ответы