здрасте всем ! я новичёк и у меня такая проблема, вот пишу я дллку код которой представлен ниже эта дллка сразу после её загрузки создаёт форму с определённым текстом мне надо сделать чтоб после вызова функции TestHello (которая находится в этой же длл) текст в окне мгновенно менялся я уже понял как он должен менятся и сделал так чтоб он менялся если переменная u12 будет не равна 1 (если скажете как можно это сделать через какую то функцию буду очень благодарен) и текст меняется но не мгновенно для того чтоб увидет результат надо как нидь "извратиться" над окном типа свернут и развернуть или сделать на весь экран... как сделать так чтоб всё мгновенно менялось ? что я сделал не так ? вот код моей длл Код (Text): .386 .model flat,stdcall option casemap:none include windows.inc include user32.inc include kernel32.inc include gdi32.inc includelib user32.lib includelib kernel32.lib includelib gdi32.lib BSIZE equ 128 .data newhwnd dd 0 hInst dd 00000000h szTitleName db 'Window Application',0 szClassName db 'ASMCLASS32',0 msg MONMSGSTRUCT <?> ; структура сообщения wc WNDCLASS <?> ; структура класса AppName db "DLL Skeleton",0 HelloMsg db "Hello,@!",0 LoadMsg db "The DLL is loaded",0 UnloadMsg db "The DLL is unloaded",0 DFF db 'd',0 u12 db 1 ThreadCreated db "A thread is created in this process",0 ThreadDestroyed db "A thread is destroyed in this process",0 buf BYTE BSIZE dup(?) stdout DWORD ? stdin DWORD ? cRead DWORD ? cWritten DWORD ? cWten DWORD ? .code DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD .if reason==DLL_PROCESS_ATTACH Invoke GetModuleHandle,0 ; получаем hInstanse Mov [hInst], eax Mov [wc.style], CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS ; устанавливаем стиль окна Mov [wc.lpfnWndProc], offset WndProc ; Mov [wc.cbClsExtra], 0 Mov [wc.cbWndExtra], 0 Mov eax, [hInst] Mov [wc.hInstance], eax Invoke LoadIcon,0,IDI_APPLICATION ; получаем значок приложения по ; умолчанию Mov [wc.hIcon], eax Invoke LoadCursorA,0,IDC_ARROW ; получаем курсор по умолчанию Mov [wc.hCursor], eax Mov [wc.hbrBackground], COLOR_BACKGROUND+1 Mov dword ptr [wc.lpszMenuName], 0 Mov dword ptr [wc.lpszClassName], offset szClassName ; задаём имя класса ;окна Invoke RegisterClassA,offset wc ; регистрируем класс окна Push 0 Push [hInst] ; дескриптор Push 0 Push 0 Push 253 ; высота Push 243 ; ширина Push 223 ; y Push 233 ; x Push WS_OVERLAPPEDWINDOW ; стиль Push offset szTitleName ; заголовок окна Push offset szClassName ; имя класса Push 0 ; дополнительный стиль Call CreateWindowEx ; создаём окно mov [newhwnd], eax ; сохраняем его дескриптор invoke ShowWindow,[newhwnd],SW_SHOWNORMAL; показываем окно invoke UpdateWindow, [newhwnd]; обновляем его invoke MessageBox,NULL,addr LoadMsg,addr AppName,MB_OK .elseif reason==DLL_PROCESS_DETACH invoke MessageBox,NULL,addr UnloadMsg,addr AppName,MB_OK .elseif reason==DLL_THREAD_ATTACH invoke MessageBox,NULL,addr ThreadCreated,addr AppName,MB_OK .else ; DLL_THREAD_DETACH invoke MessageBox,NULL,addr ThreadDestroyed,addr AppName,MB_OK .endif mov eax,TRUE ret 4 DllEntry Endp TestHello proc uses eax LOCAL ps1:PAINTSTRUCT LOCAL rect1:RECT LOCAL hdc1:HDC invoke MessageBox,NULL,addr HelloMsg,addr AppName,MB_OK mov u12, 2 ;nvoke BeginPaint,cWten, ADDR ps1 ;mov hdc1,eax ;invoke GetClientRect,cWten, ADDR rect1 ;invoke DrawText, hdc1,ADDR AppName,-1, ADDR rect1, DT_WORDBREAK or DT_CENTER or DT_VCENTER ;invoke EndPaint,cWten, ADDR ps1 ret TestHello endp WndProc proc uses ebx edi esi, hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD LOCAL hdc:HDC LOCAL ps:PAINTSTRUCT LOCAL rect:RECT mov ebx , hWnd mov cWten, ebx .IF uMsg==WM_PAINT invoke BeginPaint,hWnd, ADDR ps mov hdc,eax invoke GetClientRect,hWnd, ADDR rect .IF u12==1 invoke DrawText, hdc,ADDR HelloMsg,-1, ADDR rect, DT_WORDBREAK or DT_CENTER or DT_VCENTER .ELSE invoke DrawText, hdc,ADDR AppName,-1, ADDR rect, DT_WORDBREAK or DT_CENTER or DT_VCENTER .ENDIF invoke EndPaint,hWnd, ADDR ps .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp End DllEntry
вызови InvalidateRect для своего окна. Если тебе не нужны какие-то красивости текста, можно вместо прямого рисования текста в окне сделать static, разместить его в окне (на месте текста) и менять текст в static'e через SetWindowText. При этом тебе не нужно будет самому рисовать текст и обновлять окно. Система сама позаботится обо всём
skyman000 После mov u12, 2 вместо всего, что закомментировано, SendMessage (WM_PAINT) или просто UpdateWindow. И никаких BeginPaint/EndPaint за пределами обработчика сообщения WM_PAINT.
переписал функцию но чёт не прашет всеравно может я cWten как то не так получаю ??? а UpdateWindow я до этого тож пробывал юзать но толку 0 всерано... Код (Text): TestHello proc uses eax LOCAL ps1:PAINTSTRUCT LOCAL rect1:RECT LOCAL hdc1:HDC invoke MessageBox,NULL,addr HelloMsg,addr AppName,MB_OK mov u12, 2 ;invoke BeginPaint,cWten, ADDR ps1 ;mov hdc1,eax ;invoke GetClientRect,cWten, ADDR rect1 ;invoke DrawText, hdc1,ADDR AppName,-1, ADDR rect1, DT_WORDBREAK or DT_CENTER or DT_VCENTER ;invoke EndPaint,cWten, ADDR ps1 invoke SendMessage,cWten,WM_PAINT,0,0 ret TestHello endp а можете паказать как это реализовать программно а то мне часов 6 в инете сиден надо быдет если не больше чтоб понять как это всё слепить
пытался уже делать так invoke RedrawWindow,cWten,WM_PAINT,0,0 invoke RedrawWindow, [newhwnd],WM_PAINT,0,0 толка нету...
ВО !! invoke InvalidateRect,cWten,NULL,TRUE и всё заработало !!! ) а всё же не подскажите как это мона через static и SetWindowText реализовать??
После каждой смены текста вызывай InvalidateRect. При этом автоматом будет вызван твой callback WndProc с сообщением WM_PAINT и окно будет отрисовано вновь с новым текстом. Вот пример со статиком: Код (Text): .586 .model flat,stdcall option casemap:none ;================================================================================== include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\shell32.inc include \masm32\include\gdi32.inc include \masm32\include\advapi32.inc include \masm32\include\comctl32.inc include \masm32\include\comdlg32.inc include \masm32\include\masm32.inc include \masm32\RadASM\masm\inc\debug.inc include \masm32\RadASM\masm\inc\radbg.inc ;================================================================================== includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\shell32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\advapi32.lib includelib \masm32\lib\comctl32.lib includelib \masm32\lib\comdlg32.lib includelib \masm32\lib\masm32.lib includelib \masm32\RadASM\masm\lib\debug.lib ;================================================================================== WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD ;================================================================================== .const szClassName db "MainWinClass",0 szAppName db "App Name",0 szStaticClass db "static",0 szStaticName db "STATIC WINDOW",0 szButtonClass db "button",0 szButtonName db "BUTTON",0 szText1 db "Button 1 was pressed",0 szText2 db "Button 2 was pressed",0 ;================================================================================== .data ;================================================================================== .data? hInstance dd ? lpCmdLine dd ? hWnd dd ? hStatic dd ? hButton1 dd ? hButton2 dd ? .code ; --------------------------------------------------------------------------- start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine mov lpCmdLine,eax invoke WinMain, hInstance, NULL, lpCmdLine, SW_SHOWDEFAULT invoke ExitProcess, eax ;================================================================================== WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD LOCAL wc :WNDCLASSEX LOCAL msg :MSG LOCAL wx, wy, ww, wh :DWORD mov wc.cbSize, sizeof(WNDCLASSEX) mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, offset WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInstance pop wc.hInstance mov wc.hbrBackground,COLOR_BTNFACE+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,offset szClassName invoke LoadIcon, NULL, IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor, NULL, IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc ;------------------------------------------------- mov ww,600 mov wh,400 invoke GetSystemMetrics,SM_CXSCREEN sub eax,ww shr eax,1 mov wx,eax invoke GetSystemMetrics,SM_CYSCREEN sub eax,wh shr eax,1 mov wy,eax invoke CreateWindowEx, NULL, addr szClassName, addr szAppName, 14CA0000h, ;WS_OVERLAPPEDWINDOW, wx, wy, ww, wh, NULL, NULL, hInst, NULL mov hWnd,eax .if (eax) invoke CreateWindowEx, NULL, addr szStaticClass, addr szStaticName, WS_CHILD or WS_VISIBLE or SS_CENTER, 100, 100, 300, 50, hWnd, NULL, hInst, NULL mov hStatic,eax invoke CreateWindowEx, NULL, addr szButtonClass, addr szButtonName, WS_CHILD or WS_VISIBLE, 200, 200, 100, 50, hWnd, NULL, hInst, NULL mov hButton1,eax invoke CreateWindowEx, NULL, addr szButtonClass, addr szButtonName, WS_CHILD or WS_VISIBLE, 200, 300, 100, 50, hWnd, NULL, hInst, NULL mov hButton2,eax .endif invoke ShowWindow, hWnd,SW_SHOWNORMAL invoke UpdateWindow, hWnd .while (TRUE) invoke GetMessage, addr msg, NULL, NULL, NULL .break .if (!eax) invoke TranslateMessage, addr msg invoke DispatchMessage, addr msg .endw mov eax,msg.wParam ret WinMain endp ;================================================================================== WndProc proc uses ebx hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD mov eax,uMsg .if (eax==WM_CREATE) m2m hWnd,hWin .elseif (eax==WM_COMMAND) mov eax, lParam .if (eax==hButton1) invoke SetWindowText, hStatic, addr szText1 .elseif (eax==hButton2) invoke SetWindowText, hStatic, addr szText2 .endif .elseif (eax==WM_DESTROY) invoke PostQuitMessage, NULL .else invoke DefWindowProc, hWin, uMsg, wParam, lParam ret .endif xor eax,eax ret WndProc endp end start
l_inc Насчет "SendMessage (WM_PAINT)" как альтернативы "просто UpdateWindow": "The WM_PAINT message is generated by the system and should not be sent by an application." (MSDN) Конечно, у Feng Yuan в статье "Window Contents Capturing using WM_PRINT Message" таки видим: Код (Text): ... case WM_PRINTCLIENT: SendMessage(hWnd, WM_PAINT, wParam, lParam); break; но там роль WM_PAINT несколько иная.
kero Да. Забыл об MSDN'овском предостережении. Спасибо за напоминание. Цитату из Feng Yuan я бы в качестве аргумента против уж точно не привел бы, по меньшей мере потому что не читал его.