Обучающая программа "Окна" в 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
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д