Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Прошу помощи у знатоков МАСМа Добавлено: 09.12.06 17:23  

Автор вопроса:  VerhoLom
Прошу громко не смеяться, в тонкостях ассемблирования пока не разобрался, но пытаюсь. Пытаюсь изучить МАСМ. Использую МАСМ от Хатча. Написал на нем пока всего 2 безделушки: индикатор раскладки, выводящий флажок раскладки клавиатуры в трее (правда, идея не моя, а просто ради изучения языка решил переписать на МАСМе имеющуюся программу на LCC, которая РусЛатом называется - надо же с чего-то начинать) и проблем особых не возникло.
Потом шеф где-то услыхал, что есть программа, которая на кнопке ПУСК вместо вот этого слова выводит время, вследствии чего экономится пространство на панели задач. Икать ее, естественно, никто не хочет, а этот никто хочет, чтобы программа была написана мной. Я понимаю, штука несложная, я ее на VB за 2 часа сделал, а вот потом решил попробовать ради интереса то же самое на МАСМе переписать. Вот здесь и возникли проблемы.
Кнопочка ПУСК, оказывается, перерисовывается при смене обоев на рабочем столе, смене темы и системных цветов. Был выбран вариант, при котором создается невидимое окошко и отслеживаются сообщения, приходящие ему (WM_SYSCOLORCHANGE и т. д.), а в таймере каждые 500 мс. проверять текущую минуту времени и сравнивать ее с запомненной предыдущей. Если они равны, то ничего не делаем, если нет - то читаем системное время и, соответственно, выводим его на кнопку ПУСК. Если произошло событие, при котором кнопочка пуск перерисовывается, то просто меняется значение запомненной минуты на 65 (число от фонаря) и при срабатывании таймера время будет выведено на кнопку. Проще, в принципе, некуда... Но возникла проблема: мне не удается зарегистрировать фоновое окошко. Вот недописанный исходник (споткнулся на регистрации окна):
;;========================================================
.486

;;##########################################################################
.model flat,stdcall
option casemap:none

;;##########################################################################
WinMain Proto
WndProc Proto :DWORD, :DWORD, :DWORD, :DWORD

;;##########################################################################
@GetMsg MACRO Mes:REQ, v:REQ, inst:REQ, wnd:REQ
Local mm, szRet

push eax
.data
mm db Mes,":",0Dh,0Ah,"GetLastError = 0x%02X",0Dh,0Ah,"hInstance = 0x%02X",0Dh,0Ah,"hWnd = 0x%02X",0
szRet db 0
align 4
.code
invoke wsprintf,addr szRet,addr mm,v,inst,wnd
pop eax
exitm <addr szRet>
EndM

;;##########################################################################
include windows.inc
include user32.inc
include kernel32.inc

;;##########################################################################
includelib user32.lib
includelib kernel32.lib

;;##########################################################################
.data
szClass db "start_button_time_wnd_class",0
szName db "Часы в кнопке ПУСК.",0
szWord db "%02d",0
szTimeRet db "%s:%s",0

;;##########################################################################
.data?
hInst dd ?
hWin dd ?
bOth db ?

;;##########################################################################
.code
_main:
invoke GetModuleHandle,NULL
mov hInst,eax

invoke WinMain
invoke ExitProcess,NULL

;;##########################################################################
WinMain PROC
Local wc:WNDCLASSEX, msg:MSG

;;invoke RtlFillMemory,addr wc,SizeOf wc,0
mov wc.cbSize,SizeOf WNDCLASSEX
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
mov wc.hbrBackground,COLOR_WINDOW

invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax

invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax

push hInst
pop wc.hInstance

mov wc.lpfnWndProc,offset WndProc
mov wc.lpszClassName,offset szClass
mov wc.lpszMenuName,NULL
mov wc.style,CS_VREDRAW or CS_HREDRAW

invoke RegisterClassEx,addr wc
invoke CreateWindowEx,0,addr szClass,addr szName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULL
mov hWin,eax

.If hWin == NULL
invoke GetLastError
invoke MessageBox,NULL,@GetMsg("Произошла ошибка создания фонового окна",eax,hInst,hWin),NULL,MB_ICONERROR+MB_TASKMODAL
ret
.EndIf

invoke ShowWindow,hWin,SW_SHOW
invoke UpdateWindow,hWin

.While 1
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, wPrm:DWORD, lPrm:DWORD
.If uMsg == WM_CREATE
mov eax,TRUE
ret
.EndIf
xor eax,eax
Ret
WndProc EndP
end _main
;;========================================================

Окно не создается...
Отладчук (OllyDbg) показал такую картину, что сбой идет при регистрации окна (см. вложения) - возникает ошибка ERROR_FILE_NOT_FOUND, т. е. нельзя найти хэндл исполняемого модуля программы, но invoke GetModuleHandle,NULL возвращает 00400000, т. е. хэндл модуля (см. второе вложение).
Я ради интереса прогнал в отладчике программу с выводом раскладки клавиатуры и, что интересно, хэндл модуля возвращается тот же, хотя программа может быть загружена в 2-... экземплярах. При этом все работает. Получается, что я что-то упускаю при заполнении структуры WNDCLASSEX. Попоробовал запустить экзешник на других компьютерах, так там та же история - выскакивает окошко с сообщением о той же ошибке (правда, на одном из них окно не создалось, а вот GetLastError вернул 0).
Такая вот беда... Если не сложно, подскажите, в чем ошибка? Может, я не так заполняю структуру окна?

Ответить

  Ответы Всего ответов: 10  

Номер ответа: 1
Автор ответа:
 VerhoLom



Вопросов: 20
Ответов: 285
 Профиль | | #1 Добавлено: 09.12.06 17:27
Прошу прощения за ссылки на вложения (Там снимки окон отладчика) в тексте - я текст вопроса готовил на работе и почему-то думал, что можно вложения делать. Ан нет...

Ответить

Номер ответа: 2
Автор ответа:
 JMP



Вопросов: 6
Ответов: 171
 Профиль | | #2 Добавлено: 09.12.06 19:17
Сильно не вникал, но первое что увидел

invoke CreateWindowEx,0,addr szClass,addr szName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULL


АПИ CreateWindowEx не имеет таких констант как CW_xxx

Это константы класса. Кстати их очень легко различать

WS- windows style
CW- class window

И... почему вы их(стилевые константы) все через запятую?
Их надо по И(+) это же один параметр

Ответить

Номер ответа: 3
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #3
Добавлено: 09.12.06 22:37
Вообще-то это координаты по умолчанию

Ответить

Номер ответа: 4
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #4
Добавлено: 09.12.06 22:48
В WndProc сделай в конце вызов DefWindowProc и будет тебе счастье.

Ответить

Номер ответа: 5
Автор ответа:
 JMP



Вопросов: 6
Ответов: 171
 Профиль | | #5 Добавлено: 10.12.06 13:22
Вообще-то это координаты по умолчанию

Тьфу, @#$%^&* блин, совсем ослеп

CS-Class style

сорри за дезу :)

sne, good catch ;)

vbman,

Поставте в виндовс процедуре обработку выхода(WM_DESTROY),а то окошко будет закрываться, а процесс останется в памяти работать

WndProc PROC hWnd:DWORD, uMsg:DWORD, wPrm:DWORD, lPrm:DWORD
.If uMsg == WM_CREATE
    mov eax,TRUE
    ret

.elseif uMsg == WM_DESTROY
    invoke PostQuitMessage,NULL
    mov eax, 0
    ret
.EndIf

invoke DefWindowProc ,hWnd, uMsg, wPrm, lPrm
Ret

WndProc EndP

Ответить

Номер ответа: 6
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #6
Добавлено: 11.12.06 21:08
2прыг, не поленился ибо :)

Ответить

Номер ответа: 7
Автор ответа:
 VerhoLom



Вопросов: 20
Ответов: 285
 Профиль | | #7 Добавлено: 16.12.06 15:42
А смысл, если и окна то не создается? Оно, в принципе, поначалу работало, потом я что-то (убейте меня, но не помню - что) изменил и все полетело в тар-тарары.

Ответить

Номер ответа: 8
Автор ответа:
 VerhoLom



Вопросов: 20
Ответов: 285
 Профиль | | #8 Добавлено: 16.12.06 15:44
Воспользуюсь советом товарища SNE - может и поможет, хотя - вряд ли. Окошко ж не создано. Смысл вызывать его функцию? А может я чего не догоняю...

Ответить

Номер ответа: 9
Автор ответа:
 JMP



Вопросов: 6
Ответов: 171
 Профиль | | #9 Добавлено: 21.12.06 18:07
Ну если не доверяете, то вот полностью рабочий код вашей программы:


;;========================================================
.486

;;##########################################################################
.model flat,stdcall
option casemap:none

;;##########################################################################
WinMain Proto
WndProc Proto :DWORD, :DWORD, :DWORD, :DWORD

;;##########################################################################
@GetMsg MACRO Mes:REQ, v:REQ, inst:REQ, wnd:REQ
Local mm, szRet

push eax
.data
mm db Mes,":",0Dh,0Ah,"GetLastError = 0x%02X",0Dh,0Ah,"hInstance = 0x%02X",0Dh,0Ah,"hWnd = 0x%02X",0
szRet db 0
align 4
.code
invoke wsprintf,addr szRet,addr mm,v,inst,wnd
pop eax
exitm <addr szRet>
EndM

;;##########################################################################
include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc

;;##########################################################################
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

;;##########################################################################
.data
szClass db "start_button_time_wnd_class",0
szName db "Часы в кнопке ПУСК.",0
szWord db "%02d",0
szTimeRet db "%s:%s",0

;;##########################################################################
.data?
hInst dd ?
hWin dd ?
bOth db ?

;;##########################################################################
.code
_main:
invoke GetModuleHandle,NULL
mov hInst,eax

invoke WinMain
invoke ExitProcess, eax     ; NULL

;;##########################################################################
WinMain PROC
Local wc:WNDCLASSEX, msg:MSG

;;invoke RtlFillMemory,addr wc,SizeOf wc,0
mov wc.cbSize,SizeOf WNDCLASSEX
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
mov wc.hbrBackground,COLOR_WINDOW

invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax

invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax

push hInst
pop wc.hInstance

mov wc.lpfnWndProc,offset WndProc
mov wc.lpszClassName,offset szClass
mov wc.lpszMenuName,NULL
mov wc.style,CS_VREDRAW or CS_HREDRAW

invoke RegisterClassEx,addr wc
invoke CreateWindowEx,0,addr szClass,addr szName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULL
mov hWin,eax

.If hWin == NULL
invoke GetLastError
invoke MessageBox,NULL,@GetMsg("Произошла ошибка создания фонового окна",eax,hInst,hWin),NULL,MB_ICONERROR+MB_TASKMODAL
ret
.EndIf

invoke ShowWindow,hWin,SW_SHOW
invoke UpdateWindow,hWin

.While 1
;mLoop:
;invoke PeekMessage, addr msg, hWin, 0, 0, PM_NOREMOVE  ;IF PeekMessage(msg, hWnd, 0, 0, %PM_NOREMOVE) THEN
;test eax,eax
;jz mLoop

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, wPrm:DWORD, lPrm:DWORD
.If uMsg == WM_CREATE
     mov eax,TRUE
    ret

.elseif uMsg == WM_DESTROY
      invoke PostQuitMessage,NULL
      mov eax, 0
      ret
.EndIf

invoke DefWindowProc ,hWnd, uMsg, wPrm, lPrm
Ret

WndProc EndP
end _main
;;========================================================

Ответить

Номер ответа: 10
Автор ответа:
 sne



Разработчик Offline Client

ICQ: 233286456 

Вопросов: 34
Ответов: 5445
 Web-сайт: hw.t-k.ru
 Профиль | | #10
Добавлено: 23.12.06 01:59
2vbman, ты просто бряку не пробовал на оконную процедуру ставить. на нее вм_креэйт передается, вот тока твоя функция не возвращает правильного ответа... вот окошко и рушится.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам