Windows API 용 루아 바인딩에서 작업하고 있습니다. 지금까지 나는 목록 상자 컨트롤을 기본 윈도우를 생성 할 수있었습니다 : 그것은 만들고 창을 표시하지만, 화면이 제대로 다시 그리기하지 않습니다Windows API : 간단한 창이 올바르게 다시 그려지지 않습니다.
require('Alien')
package.path = 'libs\\?.lua;libs\\?\\init.lua;' .. package.path
local function printf(...) io.write(string.format(...)) end
Windows = require('Windows')
local W = Windows
print("loaded OK")
print("Command line=", W.GetCommandLine())
local windowClassName = "testWindow"
local windowClass, window
local hInstance = assert(W.GetModuleHandle(nil))
assert(W.WM_CREATE)
assert(W.WM_CLOSE)
assert(W.WM_DESTROY)
assert(W.DefWindowProc)
assert(W.DestroyWindow)
assert(W.PostQuitMessage)
local msgID = {}
for k, v in pairs(Windows) do
if k:match('^WM_') then msgID[v] = k end
end
local function wndProc(hWnd, msg, wParam, lParam)
local id = msgID[msg] or ('%08X'):format(msg)
printf('wndProc(%08X, %20s, %08X, %08X\n',
hWnd,id, wParam, lParam)
if msg == W.WM_CREATE then
printf("window %08X create\n", hWnd)
elseif msg == W.WM_CLOSE then W.DestroyWindow(hWnd)
elseif msg == W.WM_DESTROY then W.PostQuitMessage(0)
else return W.DefWindowProc(hWnd, msg, wParam, lParam)
end
return 0
end
local wndProcCB = alien.callback(wndProc,
assert(W.LRESULT), assert(W.HWND),
assert(W.UINT), assert(W.WPARAM), assert(W.LPARAM))
windowClass = assert(W.WNDCLASSEX:new {
cbSize = assert(W.WNDCLASSEX.size),
style = bit.bor(W.CS_HREDRAW, W.CS_VREDRAW),
lpfnWndProc = assert(wndProcCB),
cbClsExtra = 0,
cbWndExtra = 0,
hInstance = assert(hInstance),
hIcon = nil,
hCursor = nil,
hbrBackground = assert(W.COLOR_APPWORKSPACE)+1,
lpszMenuName = nil,
lpszClassName = assert(windowClassName),
hIconSm = nil,
})
assert(W.RegisterClassEx(windowClass))
local dwExStyle = bit.bor(
W.WS_EX_TOOLWINDOW,
W.WS_EX_OVERLAPPEDWINDOW)
local dwStyle = bit.bor(
W.WS_OVERLAPPEDWINDOW,
W.WS_CLIPSIBLINGS,
W.WS_CLIPCHILDREN)
window = assert(W.CreateWindowEx(
assert(dwExStyle), --dwExStyle
assert(windowClassName), --lpClassName
"Test Window", --lpWindowName
assert(dwStyle), --dwStyle
assert(W.CW_USEDEFAULT), --x
assert(W.CW_USEDEFAULT), --y
420, 314, --width, height
nil, nil, assert(hInstance), nil)) --hWndParent, hMenu, hInstance, lpParam
local SWP_SHOW_ONLY = bit.bor(
W.SWP_ASYNCWINDOWPOS,
W.SWP_SHOWWINDOW,
W.SWP_NOACTIVATE,
W.SWP_NOMOVE,
W.SWP_NOSIZE,
W.SWP_NOZORDER)
W.SetWindowPos(assert(window), nil, 0, 0, 0, 0, assert(SWP_SHOW_ONLY))
local msg = assert(W.MSG:new())
while W.GetMessage(msg, 0, 0, 0) do
W.TranslateMessage(msg)
W.DispatchMessage(msg)
end
. 콘솔 출력에서 DefWindowProc에 전달하는 WM_PAINT, WM_ERASEBKGND, WM_NCPAINT 등을 많이 볼 수 있지만 핸들링하지 않는 것 같습니다.
예 스크린 :
윈도우가 처음 나타나는 , 이는 (이 경우에서와 같이) 그 배후대로의 화상을 얻어 또는 솔리드 회색으로 표시하거나. 그것은 주변을 끌고 가면서, 그 이미지를 유지하고 그 위에 드래그되는 모든 것은 유령 이미지 뒤에 남습니다. (제목 표시 줄에서 볼 수 있습니다. 활성화 된 창 뒤의 작은 흰색 버튼이 있습니다.) 화면에서 조금 끌면 더 이상 눈에 띄지는 않지만 성공적으로 다시 칠하기는 어렵습니다.
WM_PAINT, WM_ERASEBKGND 등의 다양한 처리 방법을 시도했지만 아무런 효과가 없었습니다. 예제에서는이 메시지가 처리되는 것을 표시하지 않습니다. 내가 잘못하고있는 것이 있습니까, 아니면 제가해야 할 일이 있습니까?
DefWindowProc에 메시지를 전달하지 않고 단순히 WndProc에서 0을 반환 할 수 있습니다. 다른 메시지 처리 – user1793036
@ user1793036'else return W.DefWindowProc (hWnd, msg, wParam, lParam)' – andlabs