Skip to content

Instantly share code, notes, and snippets.

@voidproc
Created November 12, 2016 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save voidproc/a8d99805f1d8161444a84388cdc63d23 to your computer and use it in GitHub Desktop.
Save voidproc/a8d99805f1d8161444a84388cdc63d23 to your computer and use it in GitHub Desktop.
#define NOMINMAX
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Siv3D.hpp>
struct DIBSection
{
HDC hdc;
HBITMAP hbmp;
HBITMAP old;
LPBYTE bits;
DIBSection(const Size& size)
{
BITMAPINFO bi {};
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biWidth = size.x;
bi.bmiHeader.biHeight = -size.y;
hbmp = ::CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
HDC hDesktopDc = ::GetDC(0);
hdc = ::CreateCompatibleDC(hDesktopDc);
::ReleaseDC(0, hDesktopDc);
old = (HBITMAP)::SelectObject(hdc, hbmp);
}
~DIBSection()
{
::SelectObject(hdc, old);
::DeleteDC(hdc);
::DeleteObject(hbmp);
}
};
void copyImageBits(Image& imgSrc, LPBYTE bitsDst)
{
for (int i : step(imgSrc.height))
{
for (int j : step(imgSrc.width))
{
bitsDst[i * imgSrc.width * 4 + j * 4 + 0] = imgSrc[i][j].b;
bitsDst[i * imgSrc.width * 4 + j * 4 + 1] = imgSrc[i][j].g;
bitsDst[i * imgSrc.width * 4 + j * 4 + 2] = imgSrc[i][j].r;
bitsDst[i * imgSrc.width * 4 + j * 4 + 3] = imgSrc[i][j].a;
}
}
}
LRESULT CALLBACK windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_NCHITTEST:
return HTCAPTION;
}
return ::DefWindowProc(hwnd, msg, wparam, lparam);
}
HWND createSubWindow(const Size& size)
{
// ウィンドウクラスの登録
const String className = L"wnd";
WNDCLASS wc {};
wc.lpfnWndProc = windowProc;
wc.hInstance = ::GetModuleHandle(NULL);
wc.lpszClassName = className.c_str();
if (::RegisterClass(&wc) == 0)
{
MessageBox::Show(L"ウィンドウクラスの登録に失敗しました。");
return NULL;
}
// ウィンドウを作成
HWND hwnd = ::CreateWindowEx(
WS_EX_LAYERED | WS_EX_TOOLWINDOW,
className.c_str(),
L"Siv3D & ULW Test App",
WS_POPUP,
0, 0, size.x, size.y,
NULL,
NULL,
::GetModuleHandle(NULL),
NULL);
if (hwnd == NULL)
{
MessageBox::Show(L"ウィンドウ作成に失敗しました。");
return NULL;
}
return hwnd;
}
void updateLayeredWindow(HWND hwnd, HDC hdc)
{
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
RECT rect;
::GetWindowRect(hwnd, &rect);
POINT point;
point.x = rect.left;
point.y = rect.top;
SIZE size;
size.cx = rect.right - rect.left;
size.cy = rect.bottom - rect.top;
POINT p {};
HDC hDesktopDc = ::GetDC(0);
::UpdateLayeredWindow(hwnd, hDesktopDc, &point, &size, hdc, &p, 0, &blend, ULW_ALPHA);
::ReleaseDC(0, hDesktopDc);
}
void Main()
{
Image img(L"Example/Siv3D-kun.png");
HWND hwnd = createSubWindow(img.size);
if (hwnd == NULL)
{
return;
}
::ShowWindow(hwnd, SW_SHOWNORMAL);
DIBSection dib(img.size);
copyImageBits(img, dib.bits);
updateLayeredWindow(hwnd, dib.hdc);
while (true)
{
MSG msg = { };
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else {
if (!System::Update())
{
break;
}
Window::ClientRect().draw(Palette::Black);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment