Decided to revert the transparency changes; I'll try flicker-free first.
This commit is contained in:
parent
956a886c5c
commit
e1486f3cd1
|
@ -37,69 +37,6 @@ static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LP
|
||||||
return forwardCommand(hwnd, uMsg, wParam, lParam);
|
return forwardCommand(hwnd, uMsg, wParam, lParam);
|
||||||
case WM_NOTIFY:
|
case WM_NOTIFY:
|
||||||
return forwardNotify(hwnd, uMsg, wParam, lParam);
|
return forwardNotify(hwnd, uMsg, wParam, lParam);
|
||||||
case WM_PAINT:
|
|
||||||
#ifndef BROKEN
|
|
||||||
/* paint the parent's background in a flicker-free way */
|
|
||||||
dc = BeginPaint(hwnd, &ps);
|
|
||||||
if (dc == NULL)
|
|
||||||
abort();//TODO
|
|
||||||
parent = GetParent(hwnd);
|
|
||||||
if (parent == NULL)
|
|
||||||
abort();//TODO
|
|
||||||
if (GetWindowRect(hwnd, &r) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
/* GetWindowRect() returns in screen coordinates; we want parent client */
|
|
||||||
client.x = r.left;
|
|
||||||
client.y = r.top;
|
|
||||||
if (ScreenToClient(parent, &client) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
if (SetWindowOrgEx(dc, client.x, client.y, NULL) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
SendMessageW(parent, WM_PRINTCLIENT, (WPARAM) dc, PRF_CLIENT);
|
|
||||||
EndPaint(hwnd, &ps);
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
/* paint the parent's background in a flicker-free way */
|
|
||||||
dc = BeginPaint(hwnd, &ps);
|
|
||||||
if (dc == NULL)
|
|
||||||
abort();//TODO
|
|
||||||
parent = GetParent(hwnd);
|
|
||||||
if (parent == NULL)
|
|
||||||
abort();//TODO
|
|
||||||
if (GetWindowRect(hwnd, &r) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
/* GetWindowRect() returns in screen coordinates; we want parent client */
|
|
||||||
client.x = r.left;
|
|
||||||
client.y = r.top;
|
|
||||||
if (ScreenToClient(parent, &client) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
rdc = CreateCompatibleDC(dc);
|
|
||||||
if (rdc == NULL)
|
|
||||||
abort();//TODO
|
|
||||||
rbitmap = CreateCompatibleBitmap(dc, r.right - r.left, r.bottom - r.top);
|
|
||||||
if (rbitmap == NULL)
|
|
||||||
abort();//TODO
|
|
||||||
prevrbitmap = SelectObject(rdc, rbitmap);
|
|
||||||
if (prevrbitmap == NULL)
|
|
||||||
abort();//TODO
|
|
||||||
if (SetWindowOrgEx(rdc, client.x, client.y, NULL) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
SendMessageW(parent, WM_PRINTCLIENT, (WPARAM) rdc, PRF_CLIENT);
|
|
||||||
if (BitBlt(dc, 0, 0, (int) (r.right - r.left), (int) (r.bottom - r.top),
|
|
||||||
rdc, 0, 0, SRCCOPY) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
if (SelectObject(rdc, prevrbitmap) != rbitmap)
|
|
||||||
abort();//TODO
|
|
||||||
if (DeleteObject(rbitmap) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
if (DeleteDC(rdc) == 0)
|
|
||||||
abort();//TODO
|
|
||||||
EndPaint(hwnd, &ps);
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
case WM_ERASEBKGND:
|
|
||||||
/* we paint our own background above */
|
|
||||||
return 1;
|
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
if (GetClientRect(hwnd, &r) == 0)
|
if (GetClientRect(hwnd, &r) == 0)
|
||||||
xpanic("error getting client rect for Window in WM_SIZE", GetLastError());
|
xpanic("error getting client rect for Window in WM_SIZE", GetLastError());
|
||||||
|
@ -121,7 +58,7 @@ DWORD makeContainerWindowClass(char **errmsg)
|
||||||
wc.hInstance = hInstance;
|
wc.hInstance = hInstance;
|
||||||
wc.hIcon = hDefaultIcon;
|
wc.hIcon = hDefaultIcon;
|
||||||
wc.hCursor = hArrowCursor;
|
wc.hCursor = hArrowCursor;
|
||||||
wc.hbrBackground = NULL; /* we paint our own background */
|
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
||||||
wc.lpszClassName = containerclass;
|
wc.lpszClassName = containerclass;
|
||||||
if (RegisterClassW(&wc) == 0) {
|
if (RegisterClassW(&wc) == 0) {
|
||||||
*errmsg = "error registering container window class";
|
*errmsg = "error registering container window class";
|
||||||
|
@ -135,7 +72,7 @@ HWND newContainer(void *data)
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
|
||||||
hwnd = CreateWindowExW(
|
hwnd = CreateWindowExW(
|
||||||
WS_EX_TRANSPARENT,
|
0,
|
||||||
containerclass, L"",
|
containerclass, L"",
|
||||||
WS_CHILD | WS_VISIBLE,
|
WS_CHILD | WS_VISIBLE,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
/* 17 july 2014 */
|
||||||
|
|
||||||
|
#include "winapi_windows.h"
|
||||||
|
#include "_cgo_export.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
This could all just be part of Window, but doing so just makes things complex.
|
||||||
|
In this case, I chose to waste a window handle rather than keep things super complex.
|
||||||
|
If this is seriously an issue in the future, I can roll it back.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define containerclass L"gouicontainer"
|
||||||
|
|
||||||
|
static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
RECT r;
|
||||||
|
HDC dc;
|
||||||
|
PAINTSTRUCT ps;
|
||||||
|
HWND parent;
|
||||||
|
POINT client;
|
||||||
|
|
||||||
|
data = (void *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
|
||||||
|
if (data == NULL) {
|
||||||
|
/* the lpParam is available during WM_NCCREATE and WM_CREATE */
|
||||||
|
if (uMsg == WM_NCCREATE) {
|
||||||
|
storelpParam(hwnd, lParam);
|
||||||
|
data = (void *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
|
||||||
|
storeContainerHWND(data, hwnd);
|
||||||
|
}
|
||||||
|
/* act as if we're not ready yet, even during WM_NCCREATE (nothing important to the switch statement below happens here anyway) */
|
||||||
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (uMsg) {
|
||||||
|
case WM_COMMAND:
|
||||||
|
return forwardCommand(hwnd, uMsg, wParam, lParam);
|
||||||
|
case WM_NOTIFY:
|
||||||
|
return forwardNotify(hwnd, uMsg, wParam, lParam);
|
||||||
|
case WM_PAINT:
|
||||||
|
#ifndef BROKEN
|
||||||
|
/* paint the parent's background in a flicker-free way */
|
||||||
|
dc = BeginPaint(hwnd, &ps);
|
||||||
|
if (dc == NULL)
|
||||||
|
abort();//TODO
|
||||||
|
parent = GetParent(hwnd);
|
||||||
|
if (parent == NULL)
|
||||||
|
abort();//TODO
|
||||||
|
if (GetWindowRect(hwnd, &r) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
/* GetWindowRect() returns in screen coordinates; we want parent client */
|
||||||
|
client.x = r.left;
|
||||||
|
client.y = r.top;
|
||||||
|
if (ScreenToClient(parent, &client) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
if (SetWindowOrgEx(dc, client.x, client.y, NULL) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
SendMessageW(parent, WM_PRINTCLIENT, (WPARAM) dc, PRF_CLIENT);
|
||||||
|
EndPaint(hwnd, &ps);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
/* paint the parent's background in a flicker-free way */
|
||||||
|
dc = BeginPaint(hwnd, &ps);
|
||||||
|
if (dc == NULL)
|
||||||
|
abort();//TODO
|
||||||
|
parent = GetParent(hwnd);
|
||||||
|
if (parent == NULL)
|
||||||
|
abort();//TODO
|
||||||
|
if (GetWindowRect(hwnd, &r) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
/* GetWindowRect() returns in screen coordinates; we want parent client */
|
||||||
|
client.x = r.left;
|
||||||
|
client.y = r.top;
|
||||||
|
if (ScreenToClient(parent, &client) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
rdc = CreateCompatibleDC(dc);
|
||||||
|
if (rdc == NULL)
|
||||||
|
abort();//TODO
|
||||||
|
rbitmap = CreateCompatibleBitmap(dc, r.right - r.left, r.bottom - r.top);
|
||||||
|
if (rbitmap == NULL)
|
||||||
|
abort();//TODO
|
||||||
|
prevrbitmap = SelectObject(rdc, rbitmap);
|
||||||
|
if (prevrbitmap == NULL)
|
||||||
|
abort();//TODO
|
||||||
|
if (SetWindowOrgEx(rdc, client.x, client.y, NULL) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
SendMessageW(parent, WM_PRINTCLIENT, (WPARAM) rdc, PRF_CLIENT);
|
||||||
|
if (BitBlt(dc, 0, 0, (int) (r.right - r.left), (int) (r.bottom - r.top),
|
||||||
|
rdc, 0, 0, SRCCOPY) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
if (SelectObject(rdc, prevrbitmap) != rbitmap)
|
||||||
|
abort();//TODO
|
||||||
|
if (DeleteObject(rbitmap) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
if (DeleteDC(rdc) == 0)
|
||||||
|
abort();//TODO
|
||||||
|
EndPaint(hwnd, &ps);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
case WM_ERASEBKGND:
|
||||||
|
/* we paint our own background above */
|
||||||
|
return 1;
|
||||||
|
case WM_SIZE:
|
||||||
|
if (GetClientRect(hwnd, &r) == 0)
|
||||||
|
xpanic("error getting client rect for Window in WM_SIZE", GetLastError());
|
||||||
|
containerResize(data, &r);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
xmissedmsg("container", "containerWndProc()", uMsg);
|
||||||
|
return 0; /* unreached */
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD makeContainerWindowClass(char **errmsg)
|
||||||
|
{
|
||||||
|
WNDCLASSW wc;
|
||||||
|
|
||||||
|
ZeroMemory(&wc, sizeof (WNDCLASSW));
|
||||||
|
wc.lpfnWndProc = containerWndProc;
|
||||||
|
wc.hInstance = hInstance;
|
||||||
|
wc.hIcon = hDefaultIcon;
|
||||||
|
wc.hCursor = hArrowCursor;
|
||||||
|
wc.hbrBackground = NULL; /* we paint our own background */
|
||||||
|
wc.lpszClassName = containerclass;
|
||||||
|
if (RegisterClassW(&wc) == 0) {
|
||||||
|
*errmsg = "error registering container window class";
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND newContainer(void *data)
|
||||||
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
|
||||||
|
hwnd = CreateWindowExW(
|
||||||
|
WS_EX_TRANSPARENT,
|
||||||
|
containerclass, L"",
|
||||||
|
WS_CHILD | WS_VISIBLE,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
100, 100,
|
||||||
|
msgwin, NULL, hInstance, data);
|
||||||
|
if (hwnd == NULL)
|
||||||
|
xpanic("container creation failed", GetLastError());
|
||||||
|
return hwnd;
|
||||||
|
}
|
Loading…
Reference in New Issue