assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 95
Текст из файла (страница 95)
Благодаря такой цепочке связей обращение к растровому изображению в памяти производится аналогично обращению к реальному окну. Напрактике это означает, что во всех функциях, выводящих изображение в окно, наместе параметра, соответствующего контексту устройства, необходимо указыватьконтекст устройства памяти. Например, функция TextOutQ будет вызываться следующим образом:pushpushpushpushpushcaUlenTXT_TEXTOUTo f f s e t @@TXT_TEXTOUT15010@@memdcTextOutAВ пятой строке этого фрагмента функции TextOutQ передается не контекст окна,а контекст виртуального окна, что и приводит к выводу не в реальное окно, а в виртуальное, являющееся растровым изображением.
Как мы уже отметили, в программа есть только одно место, где производится вывод в реальное окно, — это фрагмент программы, обрабатывающий сообщение WM_PAINT. В случае виртуального416Глава 16. Создание Windows-приложений на ассемблереокна здесь располагается функция BitBltQ, которая копирует содержимоерастрового изображения из контекста памяти в контекст реального окна. Такимобразом постоянно обеспечивается актуальное содержимое окна приложения.В листинге 16.8 приведены фрагменты текста программы на языке ассемблера, демонстрирующей практическую реализацию способа перерисовки окна приложения с использованием виртуального окна. Полный текст программы находитсясреди файлов, прилагаемых к книге, в каталоге ..\prgl6_3 данной главы.Листинг 16.8.
Фрагменты приложения prg16_3.asm;Фрагменты приложения (prg!6_3.asm) для Win32 с использованием меню;и виртуального окна для перерисовки содержимого окна;.386locals;разрешает применение локальных меток (с префиксом (в программе.model flat, STDCALL;модель памяти flat,;STDCALL - передача параметров в стиле С (справа налево),вызываемая процедура чистит за собой стекinclude windowA.inc включаемый файл с описаниями базовых структур;и констант Win32include menu.incвключаемый файл с определением имен пунктов;меню;0бъявпение внешними используемых в данной программе;функций Win32 (ASCII):extrn GetModuleHandleA:PROCextrnextrnextrnextrnextrnextrnextrnextrnextrnextrnextrnextrnextrnextrnextrnGetDC:PROCBeginPaint :PROCEndPaint:PROCMessageBoxA:PROCDrawTextA:PROCGetClientRect:PROCGetSystemMetrics:PROCCreateCompatibleDC:PROCCreateCompatibleBitmap:PROCSelectObject:PROCGetStockObject:PROCPatBlt:PROCBitBlt:PROCInvalidateRect:PROCDeleteDC:PROC.datamemdcmaxXmaxYddddddIpRectRECT<?>;!!!это глобальная переменная;!!!это глобальная переменная;!!!это глобальная переменная.
codestartproc near;точка входа в программу:WinMain:start endp;WindowProcWindowProc procarg @@hwnd:DWORD, @@mes:DWORD, @@wparam:DWORD, @@lparam:DWORDuses ebx, edi, esi, ebx ;эти регистры обязательно должны сохранятьсяlocal @@hdc:DWORD, @@hbrush:DWORD, @@hbit:DWORDcmp @@mes, WM_DESTROYУглубленное программирование на ассемблере для Win32417jewmdestroycmp @@mes.
WM_CREATEjewmcreatecmp @@mes, WM_PAINTje wmpaintcrap @@mes, WM_COMMANDje wmcommandjmp defaultwmcreate:;создание растрового изображения, совместимого с окном приложения;получим размер экрана в пикселах int GetSystemMetrics(int nlndex)pushSM_CXSCREENcallGetSystemMetricsmovmaxX, eaxpushSM_CYSCREENcallGetSystemMetricsmovmaxY, eax;лолучить контекст устройства окна на экране @@hdc=CetDC(@@hwnd)push@@hwndcallGetDCmov@@hdc, eax;получить совместимый контекст устройства памяти;memdc=CreateCompatibleDC(@@hdc)push@@hdccallCreateCompatibleDCmovmemdc, eax ;!!! memdc - глобальная переменная;получить дескриптор растрового изображения в памяти; @@hbit=CreateCompatibleBitmap(@@hdc, @@maxX, @@maxY)pushmaxYpushmaxXpush@@hdccallCreateCompatibleBitmapmov@@hbit, eax;выбираем растр в контекст памяти SelectObject(memdc, @@hbit)push@@hbitpushmemdccallSelectObject•.выполним первичное заполнение растра серым цветом;получим дескриптор серой кисти hbrush=GetStockObject(GRAY_BRUSH)pushGRAY_BRUSHcallGetStockObjectmov@@hbrush, eax;выбираем кисть в контекст памяти SelectObject(memdc, @@hbrush)push@@hbrushpushmemdccallSelectObject;заполняем выбранной кистью виртуальное окно;BOOL PatBlt(HDC hdc, int nXLeft.
int nYLeft. int nWidth,;int nHeight, DWORD dwRop)pushPATCOPYpushmaxYpushmaxXpushNULLpushNULLpushmemdccallPatBlt;освободим контекст устройства ReleaseDC(@@hwnd, @@hdc)push@@hdcpush@>@hwndcallReleaseDC;обозначим создание окна звуковым эффектом;готовим вызов функции BOOL PlaySound(LPCSTR pszSound,;HMODULE hmod, DWORD fdwSound)pushSND_SYNC+SND_FILENAMEпродолжение •&14 Зак. 256418Глава 16.
Создание Windows-приложений на ассемблереЛистинг16.8(продолжение)pushpushcallвозвращаемmovNULLoffset playFileCreatePlaySoundAзначение Оeax, 0jmpexit_wndprocwmpaint:;получим контекст устройства HOC BeginPaint(HWND hwnd,;LPPAINTSTRUCT IpPaint);pushoffset pspush@@hwndcallBeginPaintmov@@hdc, eax;обозначим перерисовку окна звуковым эффектомpushSND_SYNC+SND_FILENAMEpushNULLpushoffset playFilePaintcallPlaySoundA;выведем строку текста в окно BOOLTextOut(HDChdc,intnXStart,;int nYStart, LPCTSTRlpString,intcbString);pushMesWindowLenpushoffset MesWindowpush100push10pushmemdccallTextOutAвывод виртуального окна в реальное окноBOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth,int nHeight, HOC hdcSrc, i n t nXSrc, int nYSrc, DWORD dwRop)pushSRCCOPYpushNULLpushNULLpushmemdcpushmaxYpushmaxXpushNULLpushNULLpush@@hdccallBitBltосвободить контекст BOOL EndPaint(HWND hWnd,;CONST PAINTSTRUCT *lpPaint);pushoffset pspush@@hwndcallEndPaintmoveax, 0 возвращаемое значение - 0jmpexit_wndprocwmdestroy:wmcommand:;вызов процедуры обработки сообщений от меню;MenuProc (DWORD @@hwnd, DWORD @@wparam)push@@wparampush@@hwndcallMenuProcjmpexit_wndprocdefault:exi t_wndproc:retWindowProc endp;MenuProc;обработка сообщений от меню--Углубленное программирование на ассемблере для Win32419MenuProcprocarg @@hwnd:DWORD, @@wparam:DWORDuses ebxlocalmov ebx, @@wparam;в Ьх идентификатор менюjrap @@exit@@idmdrawtext:;получим размер рабочей области BOOL GetClientRect(HWND hWnd,;LPRECT IpRect);pushoffset IpRectpush@@hwndcallGetClientRect;выведем строку текста в окно int DrawText(HDC hDC,;LPCTSTR IpString, int nCount, length,;LPRECT IpRect, UINT uFormat);pushDT_SINGLELINE+DT_BOTTOMpushoffset IpRectpush-1pushoffset @@TXT_DRAWTEXTpushmemdccallDrawTextA;генерация сообщения WM_PAINT для вывода строки на экран;BOOL InvalidateRect(HWND hWnd, CONST RECT «IpRect, BOOL bErase)push1pushNULLpush@@hwndcallInvalidateRectjmp@@exit@@idmtextout:;выведем строку текста в окно BOOL TextOut(HDC hdc, int nXStart,;int nYStart, LPCTSTR IpString, int cbString)pushlenTXT_TEXTOUTpushoffset @@TXT_TEXTOUTpush150push10pushmemdccallTextOutA;генерация сообщения WM_PAINT для вывода строки на экранpush0pushNULLpush@@hwndcallInvalidateRectjmp@@exit@@idmlength:jmp@@exit@@idmrectangle:jmp@@exit@@idmpeacock:jmp@@exit@@idmlaces:jmp@@exit@@idmabout:jmp@@exitigexit:moveax, 0ret@@TXT_ABOUT db 'IDM_ABOUT', 0продолжение &420Глава 16.
Создание Windows-приложений на ассемблереЛистинг 16.8(продолжение)@@TXT_LACES db ' IDMJ.ACES ' , 0@@ТХТ_РЕАСОСК db 'IDM_PEACOCK', Э@@TXT_RECTANGLE db 'IDM_RECTANGLE', 0@@TXT_l_ENGTHdb ' IDM_LENGTH ' , 0@@TXT_TEXTOUTdb 'Текст выведен функцией TEXTOUT'lenTXT_TEXTOUT=$-@@TXT_TEXTOUT1@@TXT_DRAWTEXT db'Текст выведен функцией D R A W T E X T , 0MenuProcendpend startВозможно, результаты работы программы из листинга 16.8 вам покажутся неочень красивыми, но такая цель и не ставилась. Назначение этой программы —исследовательское. Из-за задержек, вызванных воспроизведением звуковых файлов, хорошо виден момент перерисовки окна. Такую технологию можно использовать для более глубокого исследования механизмов работы Windows.Окна диалога в Windows-приложенияхОкна диалога являются важными и популярными элементами пользовательскогоинтерфейса Windows.
Редкое оконное приложение обходится без окон этого типа.Физически окно диалога представляет собой специфическое окно, работа с которым поддерживается на уровне интерфейса Win32 API Windows. Основное назначение этого окна — помочь пользователю сформировать информацию, необходимую для управления работой приложения. Наиболее наглядные примеры оконэтого типа — окна диалога в текстовом редакторе. С их помощью можно задатьпараметры шрифта, страницы или печати. Очень важно, что разработка таких оконне требует программирования.
Для описания окон диалога система Windows поддерживает специальный тип ресурса. Более подробно о том, как в программе должны выглядеть окна диалога, из каких элементов они состоят, а также о деталяхуправления этими окнами вы можете почитать в других источниках. Наша цель —показать, каким образом работа с окнами диалога организуется программой, написанной на языке ассемблера.С точки зрения технологии, организация работы с окнами диалога, реализуемая программой на ассемблере, ничем не отличается от того, как это делается налюбом другом языке.