News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Debugging inside a WM_PAINT handler

Started by jj2007, March 20, 2016, 07:57:56 PM

Previous topic - Next topic

jj2007

It is notoriously difficult to debug a Windows application inside a WM_PAINT handler, the main reason being that you can't see your output and the debugger's output at the same time.

One option is to use instead the deb macro, which allows to display registers (reg32, xmm, FPU), flags, local and global variables to the console.

The code below is almost identical with \masm32\examples\exampl01\generic\generic.asm, except that, as an option, you can use the deb macro to display values to the console. With useMB=0, the code does not use MasmBasic and remains a pure Masm32 application. The screenshot below shows what you see with useMB=1. The library can be downloaded here.

useMB=0 ; put 1 to use MasmBasic
if useMB
include \masm32\MasmBasic\MasmBasic.inc ; *** load MasmBasic includes ***
else
include \masm32\include\masm32rt.inc ; **** load standard Masm32 includes ****
endif
winX equ 500
winY equ 0
winW equ 600
winH equ 400
.data ; initialised data section
MyWinStyle = CS_HREDRAW or CS_VREDRAW or CS_OWNDC ; see pros and cons of CS_OWNDC
wcx WNDCLASSEX <WNDCLASSEX, MyWinStyle, WndProc, 0, 0, 1, 2, 3, COLOR_WINDOW+1, 0, txClass, 4>
txClass db "Masm32GUI", 0 ; class name, will be registered below
.code
WinMain proc
LOCAL msg:MSG
  wc equ [ebx.WNDCLASSEX] ; we use an equate for better readability
  mov ebx, offset wcx
  mov wc.hInstance, rv(GetModuleHandle, 0) ; rv ("return value") is a Masm32 macro
  mov wc.hIcon, rv(LoadIcon, eax, IDI_APPLICATION)
  mov wc.hIconSm, eax ; the rv macro returns results in eax
  mov wc.hCursor, rv(LoadCursor, NULL, IDC_ARROW) ; get a cursor
  invoke RegisterClassEx, addr wc ; the window class needs to be registered
  invoke CreateWindowEx, WS_EX_ACCEPTFILES, wc.lpszClassName, chr$("Hello World"), ; set window title here
     WS_OVERLAPPEDWINDOW or WS_VISIBLE,
     winX, winY, winW, winH, ; window position: x, y, width, height
     NULL, rv(LoadMenu, wc.hInstance, 100), wc.hInstance, NULL
  .While 1
invoke GetMessage, addr msg, 0, 0, 0
inc eax
shr eax, 1
.Break .if Zero? ; 0 (OK) or -1 (error)
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
  .Endw
  invoke ExitProcess, msg.wParam
WinMain endp
WndProc proc uses esi edi ebx hWnd, uMsg, wParam:WPARAM, lParam:LPARAM
  SWITCH uMsg
  CASE WM_PAINT
  sub esp, PAINTSTRUCT ; simple way to create a structure on the stack
invoke BeginPaint, hWnd, esp

xchg eax, esi
PtDC equ esi

xor ebx, ebx
.Repeat
inc ebx
push ebx
fild dword ptr [esp]
fmul FP4(0.0174533) ; *PI/180
fsin
if useMB
deb 30, "Sinus", ST(0) ; display the first 30
endif
mov dword ptr [esp], winH-80
fild dword ptr [esp]
fmul
if useMB
deb 30, "x WinH", ST(0)
endif
fistp dword ptr [esp]
pop eax
invoke SetPixel, PtDC, ebx, eax, 0FFh
.Until ebx>400
invoke EndPaint, hWnd, esp
  add esp, PAINTSTRUCT
   CASE WM_DESTROY ; quit after WM_CLOSE
invoke PostQuitMessage, NULL
  ENDSW
  invoke DefWindowProc, hWnd, uMsg, wParam, lParam ; default processing
  ret
WndProc endp
end WinMain