Reworking the code using a slightly altered DrawChar procedure than shown above, now called "DrawCell". It has a single extra argument for whether the cell should be selected (blue background) or highlighted (orange background) the text color will remain black in either case including default case. Only changed text color for the demo that is shown above.
Once I get the painting functions finished I can then work on the other controls code, and getting mouse clicks of course.
; This source code written by swordfish @ masm32.com
include \masm32\include\masm32rt.inc
RegWindow proto :dword, :dword
WinMain proto :dword, :dword, :dword
WndProc proto :dword, :dword, :dword, :dword
CenterMain proto :dword, :dword, :dword
DrawBitmap proto :dword, :dword, :dword, :dword, :dword, :dword
DrawCells proto :dword, :dword, :dword, :dword
wwidth equ 1026
wheight equ 768
ws equ WS_BORDER or WS_CAPTION or WS_MINIMIZEBOX or WS_SYSMENU
menuid equ 600
iconid equ 500
hilite equ 1
select equ 2
.data?
hWnd dd ?
hInstance dd ?
hBlue dd ?
hOrange dd ?
CellFont dd ?
hBackBmp dd ?
.data
align 16
board label byte
db 1, 2, 3, 4, 5, 6, 7, 8, 9
db 4, 5, 6, 7, 8, 9, 1, 2, 3
db 7, 8, 9, 1, 2, 3, 4, 5, 6
db 2, 3, 4, 5, 6, 7, 8, 9, 1
db 5, 6, 7, 8, 9, 1, 2, 3, 4
db 8, 9, 1, 2, 3, 4, 5, 6, 7
db 3, 4, 5, 6, 7, 8, 9, 1, 2
db 6, 7, 8, 9, 1, 2, 3, 4, 5
db 9, 1, 2, 3, 4, 5, 6, 7, 8
str1 db "1", 0
str2 db "2", 0
str3 db "3", 0
str4 db "4", 0
str5 db "5", 0
str6 db "6", 0
str7 db "7", 0
str8 db "8", 0
str9 db "9", 0
.const
x1 dd 4
x2 dd 70
x3 dd 136
x4 dd 204
x5 dd 270
x6 dd 336
x7 dd 404
x8 dd 470
x9 dd 536
y1 dd 4
y2 dd 70
y3 dd 136
y4 dd 204
y5 dd 270
y6 dd 336
y7 dd 404
y8 dd 470
y9 dd 536
dname db "sudoku", 0
wclass db "SUDOKUCLASS", 0
about db "sudoku v1.0 by swordfish 2022", 0
.code
start:
invoke GetModuleHandle, 0
mov hInstance, eax
invoke RegWindow, hInstance, addr wclass
invoke WinMain, hInstance, addr wclass, addr dname
invoke ExitProcess, eax
WinMain proc hi:dword, cn:dword, dn:dword
local msg:MSG, Wtx:dword, Wty:dword
invoke CreateWindowEx, 0, cn, dn, ws, 0, 0, 0, 0, 0, 0, hi, 0
mov hWnd, eax
invoke LoadMenu, hi, menuid
invoke SetMenu, hWnd, eax
invoke ShowWindow, hWnd, SW_SHOWNORMAL
invoke UpdateWindow, hWnd
StartLoop:
invoke GetMessage, addr msg, 0, 0, 0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
jmp StartLoop
ExitLoop:
return msg.wParam
WinMain endp
WndProc proc hWin:dword, uMsg:dword, wParam:dword, lParam:dword
local hDC:dword, ps:PAINTSTRUCT, hMemDC:dword, hOld:dword
.if uMsg == WM_CREATE
invoke CenterMain, hWin, wwidth, wheight
invoke LoadBitmap, hInstance, 450
mov hBackBmp, eax
invoke CreateSolidBrush, 0077BBFFh
mov hOrange, eax
invoke CreateSolidBrush, 00FFBB77h
mov hBlue, eax
fn RetFontHandle, "simhei", 48, 100
mov CellFont, eax
.elseif uMsg == WM_COMMAND
.if wParam == 86
invoke SendMessage, hWin, WM_SYSCOMMAND, SC_CLOSE, 0
.elseif wParam == 99
fn MessageBox, hWin, addr about, addr dname, MB_OK
.endif
.elseif uMsg == WM_PAINT
invoke BeginPaint, hWin, addr ps
mov hDC, eax
invoke DrawBitmap, hDC, hBackBmp, 0, 0, 872, 604 ;; background
invoke DrawCells, hDC, addr board, addr x1, addr y1 ;; cells
invoke EndPaint, hWin,addr ps
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage, 0
return 0
.endif
invoke DefWindowProc, hWin, uMsg, wParam, lParam
ret
WndProc endp
RegWindow proc hi:dword, cn:dword
local wc:WNDCLASSEX, icn:dword
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, 0
mov wc.cbWndExtra, 0
mrm wc.hInstance, hi
mov wc.hbrBackground, COLOR_BTNFACE+6
mov wc.lpszMenuName, 0
mrm wc.lpszClassName, cn
invoke LoadIcon, hi, iconid
mov wc.hIcon, eax
mov icn, eax
invoke LoadCursor, 0, IDC_ARROW
mov wc.hCursor, eax
mrm wc.hIconSm, icn
invoke RegisterClassEx, addr wc
ret
RegWindow endp
CenterMain proc hWin:dword, wd:dword, ht:dword
local rct:RECT, h:dword, w:dword, x:dword, y:dword
@@: ; dynamically adjusting width of the window for proper client rect size
invoke MoveWindow, hWin, x, y, wd, ht, 0
invoke GetClientRect, hWin, addr rct
mov eax, rct.right
sub eax, rct.left
.if eax > 872 ; desired client rect width
dec wd
jmp @b
.elseif eax < 872
inc wd
jmp @b
.endif
@@: ; dynamically adjusting height of the window for proper client rect size
invoke MoveWindow, hWin, x, y, wd, ht, 0
invoke GetClientRect, hWin, addr rct
mov eax, rct.bottom
sub eax, rct.top
.if eax > 604 ; desired client rect height
dec ht
jmp @b
.elseif eax < 604
inc ht
jmp @b
.endif
invoke GetSystemMetrics, SM_CYMENU
add ht, eax
invoke SystemParametersInfoA, SPI_GETWORKAREA, 0, addr rct, 0
mov eax, rct.right
sub eax, wd
sar eax, 1
mov x, eax
mov eax, rct.bottom
sub eax, ht
sar eax, 1
mov y, eax
invoke MoveWindow, hWin, x, y, wd, ht, TRUE
ret
CenterMain endp
DrawBitmap proc hDC:dword, hBmp:dword, xc:dword, yc:dword, wd:dword, ht:dword
local hOld:dword, hMemDC:dword
push esi
push edi
push ebx
push edx
push ecx
invoke CreateCompatibleDC, NULL
mov hMemDC, eax
invoke SelectObject, hMemDC, hBmp ; select object to blit to hMemDC
mov hOld, eax
invoke BitBlt, hDC, xc, yc, wd, ht, hMemDC, 0, 0, SRCCOPY ; blit hMemDC to hDC
invoke SelectObject, hMemDC, hOld ; select object for deletion
invoke DeleteObject, hMemDC ; delete oject here
invoke DeleteDC, hMemDC
pop ecx
pop edx
pop ebx
pop edi
pop esi
ret
DrawBitmap endp
DrawCell proc hDC:dword, txt:dword, x:dword, y:dword, hi:dword
local rct:RECT, hMemDC:dword, hOld:dword
push esi
push edi
push ebx
push edx
push ecx
mov eax, x
mov rct.left, eax
add eax, 64
mov rct.right, eax
mov eax, y
mov rct.top, eax
add eax, 64
mov rct.bottom, eax
.if hi == hilite
invoke FillRect, hDC, addr rct, hBlue
.elseif hi == select
invoke FillRect, hDC, addr rct, hOrange
.endif
add rct.top, 7 ;; need padding to properly vertical center
invoke SelectObject, hDC, CellFont
invoke SetBkMode, hDC, TRANSPARENT
invoke DrawText, hDC, txt, 1, addr rct, DT_CENTER or DT_VCENTER
pop ecx
pop edx
pop ebx
pop edi
pop esi
ret
DrawCell endp
DrawCells proc hDC:dword, lpBoard:dword, lpx:dword, lpy:dword
push ebx
push esi
push edi
push edx
push ecx
mov edx, lpx
mov esi, lpBoard
xor ebx, ebx
ttop:
xor edi, edi
mov ecx, lpy
top:
.if byte ptr [esi+edi] == 1
invoke DrawCell, hDC, addr str1, dword ptr [ecx], dword ptr [edx], 0
.elseif byte ptr [esi+edi] == 2
invoke DrawCell, hDC, addr str2, dword ptr [ecx], dword ptr [edx], 0
.elseif byte ptr [esi+edi] == 3
invoke DrawCell, hDC, addr str3, dword ptr [ecx], dword ptr [edx], 0
.elseif byte ptr [esi+edi] == 4
invoke DrawCell, hDC, addr str4, dword ptr [ecx], dword ptr [edx], 0
.elseif byte ptr [esi+edi] == 5
invoke DrawCell, hDC, addr str5, dword ptr [ecx], dword ptr [edx], 0
.elseif byte ptr [esi+edi] == 6
invoke DrawCell, hDC, addr str6, dword ptr [ecx], dword ptr [edx], 0
.elseif byte ptr [esi+edi] == 7
invoke DrawCell, hDC, addr str7, dword ptr [ecx], dword ptr [edx], 0
.elseif byte ptr [esi+edi] == 8
invoke DrawCell, hDC, addr str8, dword ptr [ecx], dword ptr [edx], 0
.elseif byte ptr [esi+edi] == 9
invoke DrawCell, hDC, addr str9, dword ptr [ecx], dword ptr [edx], 0
.endif
add ecx, 4
inc edi
cmp edi, 9
jnz top
add esi, 9
inc ebx
add edx, 4
cmp ebx, 9
jnz ttop
pop ecx
pop edx
pop edi
pop esi
pop ebx
ret
DrawCells endp
end start
As of now, only reading and displaying the game board.