-
-
Save mirichi/00fa8b50bbd4847d8b6f1d0a99d59428 to your computer and use it in GitHub Desktop.
アクティベーションコンテキストサンプル
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'tmpdir' | |
require "fiddle/import" | |
require 'fiddle/types' | |
width = 320 | |
height = 240 | |
# WindowsAPIのインターフェイス | |
module WinAPI | |
extend Fiddle::Importer | |
dlload "gdi32", "ole32", "user32", "kernel32" | |
include Fiddle::Win32Types | |
# 型の定義 | |
typealias "HMENU", "unsigned int" | |
typealias "HICON", "unsigned int" | |
typealias "HCURSOR", "unsigned int" | |
typealias "HBRUSH", "unsigned int" | |
typealias "HMODULE", "unsigned int" | |
typealias "WNDPROC", "void *" | |
typealias "LPVOID", "void *" | |
typealias "LPMSG", "void *" | |
typealias "WINBOOL", "int" | |
typealias "LONG", "long" | |
typealias "WPARAM", "void *" | |
typealias "LPARAM", "void *" | |
typealias "LRESULT", "void *" | |
typealias "LPRECT", "void *" | |
typealias "PACTCTX", "void *" | |
typealias "LPCWSTR", "char *" | |
typealias "LPCTSTR", "char *" | |
typealias "USHORT", "unsigned short" | |
typealias "LANGID", "unsigned short" | |
# WindowsAPIの定義 | |
extern "HWND CreateWindowExA(DWORD, LPCSTR, LPCSTR, DWORD, DWORD, DWORD, int, int, HWND, HMENU, HINSTANCE, LPVOID)" | |
extern "ATOM RegisterClassExA(void *)" | |
extern "HMODULE GetModuleHandleA(LPCSTR)" | |
extern "UINT DefWindowProcA(HWND, UINT, UINT, LONG)" | |
extern "WINBOOL GetMessageA(LPMSG, HWND, UINT, UINT)" | |
extern "WINBOOL TranslateMessage(LPMSG)" | |
extern "LRESULT DispatchMessageA(LPMSG)" | |
extern "HCURSOR SetCursor(HCURSOR)" | |
extern "HCURSOR LoadCursorA(HINSTANCE, LPCSTR)" | |
extern "WINBOOL AdjustWindowRect(LPRECT, DWORD, WINBOOL)" | |
extern "void PostQuitMessage(int)" | |
extern "WINBOOL DestroyWindow(HWND)" | |
extern "HANDLE CreateActCtx(PACTCTX)" | |
extern "BOOL ActivateActCtx(HANDLE, void **)" | |
extern "void ReleaseActCtx(HANDLE)" | |
# 構造体の定義 | |
WNDCLASSEX = struct([ | |
"UINT cbSize", | |
"UINT style", | |
"WNDPROC lpfnWndProc", | |
"int cbClsExtra", | |
"int cbWndExtra", | |
"HINSTANCE hInstance", | |
"HICON hIcon", | |
"HCURSOR hCursor", | |
"HBRUSH hbrBackground", | |
"LPCSTR lpszMenuName", | |
"LPCSTR lpszClassName", | |
"HICON hIconSm" | |
]) | |
MSG = struct([ | |
"HWND hwnd", | |
"UINT message", | |
"WPARAM wParam", | |
"LPARAM lParam", | |
"DWORD time", | |
"LONG x", | |
"LONG y" | |
]) | |
RECT = struct([ | |
"LONG left", | |
"LONG top", | |
"LONG right", | |
"LONG bottom" | |
]) | |
GUID = struct([ | |
"unsigned long Data1", | |
"unsigned short Data2", | |
"unsigned short Data3", | |
"unsigned char Data4[8]" | |
]) | |
ACTCTX = struct([ | |
"ULONG cbSize", | |
"DWORD dwFlags", | |
"LPCWSTR lpSource", | |
"USHORT wProcessorArchitecture", | |
"LANGID wLangId", | |
"LPCTSTR lpAssemblyDirectory", | |
"LPCTSTR lpResourceName", | |
"LPCTSTR lpApplicationName", | |
"HMODULE hModule" | |
]) | |
# 使いそうな定数の定義 | |
CS_VREDRAW = 0x0001 | |
CS_HREDRAW = 0x0002 | |
CS_DBLCLKS = 0x0008 | |
CS_OWNDC = 0x0020 | |
CS_CLASSDC = 0x0040 | |
CS_PARENTDC = 0x0080 | |
CS_NOCLOSE = 0x0200 | |
CS_SAVEBITS = 0x0800 | |
CS_BYTEALIGNCLIENT = 0x1000 | |
CS_BYTEALIGNWINDOW = 0x2000 | |
CS_GLOBALCLASS = 0x4000 | |
CS_IME = 0x00010000 | |
CS_DROPSHADOW = 0x00020000 | |
COLOR_SCROLLBAR = 0 | |
COLOR_BACKGROUND = 1 | |
COLOR_ACTIVECAPTION = 2 | |
COLOR_INACTIVECAPTION = 3 | |
COLOR_MENU = 4 | |
COLOR_WINDOW = 5 | |
COLOR_WINDOWFRAME = 6 | |
COLOR_MENUTEXT = 7 | |
COLOR_WINDOWTEXT = 8 | |
COLOR_CAPTIONTEXT = 9 | |
COLOR_ACTIVEBORDER = 10 | |
COLOR_INACTIVEBORDER = 11 | |
COLOR_APPWORKSPACE = 12 | |
COLOR_HIGHLIGHT = 13 | |
COLOR_HIGHLIGHTTEXT = 14 | |
COLOR_BTNFACE = 15 | |
COLOR_BTNSHADOW = 16 | |
COLOR_GRAYTEXT = 17 | |
COLOR_BTNTEXT = 18 | |
COLOR_INACTIVECAPTIONTEXT = 19 | |
COLOR_BTNHIGHLIGHT = 20 | |
COLOR_3DDKSHADOW = 21 | |
COLOR_3DLIGHT = 22 | |
COLOR_INFOTEXT = 23 | |
COLOR_INFOBK = 24 | |
COLOR_HOTLIGHT = 26 | |
COLOR_GRADIENTACTIVECAPTION = 27 | |
COLOR_GRADIENTINACTIVECAPTION = 28 | |
COLOR_MENUHILIGHT = 29 | |
COLOR_MENUBAR = 30 | |
COLOR_DESKTOP = COLOR_BACKGROUND | |
COLOR_3DFACE = COLOR_BTNFACE | |
COLOR_3DSHADOW = COLOR_BTNSHADOW | |
COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT | |
COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT | |
COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT | |
WS_OVERLAPPED = 0x00000000 | |
WS_POPUP = 0x80000000 | |
WS_CHILD = 0x40000000 | |
WS_MINIMIZE = 0x20000000 | |
WS_VISIBLE = 0x10000000 | |
WS_DISABLED = 0x08000000 | |
WS_CLIPSIBLINGS = 0x04000000 | |
WS_CLIPCHILDREN = 0x02000000 | |
WS_MAXIMIZE = 0x01000000 | |
WS_CAPTION = 0x00C00000 | |
WS_BORDER = 0x00800000 | |
WS_DLGFRAME = 0x00400000 | |
WS_VSCROLL = 0x00200000 | |
WS_HSCROLL = 0x00100000 | |
WS_SYSMENU = 0x00080000 | |
WS_THICKFRAME = 0x00040000 | |
WS_GROUP = 0x00020000 | |
WS_TABSTOP = 0x00010000 | |
WS_MINIMIZEBOX = 0x00020000 | |
WS_MAXIMIZEBOX = 0x00010000 | |
WS_TILED = WS_OVERLAPPED | |
WS_ICONIC = WS_MINIMIZE | |
WS_SIZEBOX = WS_THICKFRAME | |
WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) | |
WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW | |
WS_POPUPWINDOW = (WS_POPUP | WS_BORDER | WS_SYSMENU) | |
WS_CHILDWINDOW = (WS_CHILD) | |
CW_USEDEFAULT = 0x80000000 | |
WM_NULL = 0x0000 | |
WM_CREATE = 0x0001 | |
WM_DESTROY = 0x0002 | |
WM_MOVE = 0x0003 | |
WM_SIZE = 0x0005 | |
WM_ACTIVATE = 0x0006 | |
WA_INACTIVE = 0 | |
WA_ACTIVE = 1 | |
WA_CLICKACTIVE = 2 | |
WM_SETFOCUS = 0x0007 | |
WM_KILLFOCUS = 0x0008 | |
WM_ENABLE = 0x000A | |
WM_SETREDRAW = 0x000B | |
WM_SETTEXT = 0x000C | |
WM_GETTEXT = 0x000D | |
WM_GETTEXTLENGTH = 0x000E | |
WM_PAINT = 0x000F | |
WM_CLOSE = 0x0010 | |
WM_QUIT = 0x0012 | |
WM_ERASEBKGND = 0x0014 | |
WM_SYSCOLORCHANGE = 0x0015 | |
WM_SHOWWINDOW = 0x0018 | |
WM_WININICHANGE = 0x001A | |
WM_SETTINGCHANGE = WM_WININICHANGE | |
WM_DEVMODECHANGE = 0x001B | |
WM_ACTIVATEAPP = 0x001C | |
WM_FONTCHANGE = 0x001D | |
WM_TIMECHANGE = 0x001E | |
WM_CANCELMODE = 0x001F | |
WM_SETCURSOR = 0x0020 | |
WM_MOUSEACTIVATE = 0x0021 | |
WM_CHILDACTIVATE = 0x0022 | |
WM_QUEUESYNC = 0x0023 | |
IDC_ARROW = 32512 | |
IDC_IBEAM = 32513 | |
IDC_WAIT = 32514 | |
IDC_CROSS = 32515 | |
IDC_UPARROW = 32516 | |
IDC_SIZE = 32640 | |
IDC_ICON = 32641 | |
IDC_SIZENWSE = 32642 | |
IDC_SIZENESW = 32643 | |
IDC_SIZEWE = 32644 | |
IDC_SIZENS = 32645 | |
IDC_SIZEALL = 32646 | |
IDC_NO = 32648 | |
IDC_HAND = 32649 | |
IDC_APPSTARTING = 32650 | |
IDC_HELP = 32651 | |
BS_PUSHBUTTON = 0x00000000 | |
end | |
# ウィンドウプロシージャ | |
class WndProc < Fiddle::Closure | |
def call(hWnd, msg, wParam, lParam) | |
case msg | |
when WinAPI::WM_CLOSE | |
WinAPI::DestroyWindow(hWnd) | |
when WinAPI::WM_DESTROY | |
WinAPI::PostQuitMessage(0) | |
else | |
return WinAPI::DefWindowProcA(hWnd, msg, wParam, lParam) | |
end | |
return 0 | |
end | |
end | |
# 実行中のプログラムのインスタンスハンドル取得 | |
hInstance = WinAPI::GetModuleHandleA(0) | |
hActCtx = nil | |
open(Dir.tmpdir + "/XPThemes.manifest", "wt") do |f| | |
f.write(<<"EOS") | |
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> | |
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | |
<dependency> | |
<dependentAssembly> | |
<assemblyIdentity | |
type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" | |
processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> | |
</dependentAssembly> | |
</dependency> | |
</assembly> | |
EOS | |
end | |
# アクティベーションコンテキスト | |
actctx = WinAPI::ACTCTX.new(Fiddle::Pointer.malloc(WinAPI::ACTCTX.size)) | |
actctx.cbSize = WinAPI::ACTCTX.size | |
actctx.lpSource = Dir.tmpdir + "/XPThemes.manifest"#.encode("UTF-16LE") | |
hActCtx = WinAPI::CreateActCtx(actctx) | |
cookie = Fiddle::Pointer.malloc(4) | |
WinAPI::ActivateActCtx(hActCtx, cookie) | |
# ウィンドウプロシージャ | |
wndproc = WndProc.new(Fiddle::TYPE_LONG, [-Fiddle::TYPE_INT, -Fiddle::TYPE_INT, -Fiddle::TYPE_INT, Fiddle::TYPE_INT]) | |
# WNDCLASSEX構造体作成 | |
wcex = WinAPI::WNDCLASSEX.malloc | |
wcex.cbSize = WinAPI::WNDCLASSEX.size | |
wcex.style = WinAPI::CS_HREDRAW | WinAPI::CS_VREDRAW | |
wcex.lpfnWndProc = wndproc | |
wcex.cbClsExtra = 0 | |
wcex.cbWndExtra = 0 | |
wcex.hInstance = hInstance | |
wcex.hIcon = 0 | |
wcex.hIconSm = 0 | |
wcex.hCursor = 0 | |
wcex.hbrBackground = WinAPI::COLOR_WINDOW | |
wcex.lpszMenuName = nil | |
wcex.lpszClassName = "test" | |
# (Windowsの)クラス定義 | |
WinAPI::RegisterClassExA(wcex) | |
# ウィンドウサイズ計算 | |
rect = WinAPI::RECT.malloc | |
rect.top = 0 | |
rect.left = 0 | |
rect.right = width | |
rect.bottom = height | |
WinAPI::AdjustWindowRect(rect, WinAPI::WS_OVERLAPPED | WinAPI::WS_CAPTION | WinAPI::WS_SYSMENU | WinAPI::WS_MINIMIZEBOX, 0); | |
# ウィンドウ作成 | |
hWnd = WinAPI::CreateWindowExA(0, "test", "Test Window", | |
WinAPI::WS_OVERLAPPED | WinAPI::WS_CAPTION | WinAPI::WS_SYSMENU | WinAPI::WS_MINIMIZEBOX | WinAPI::WS_VISIBLE, | |
WinAPI::CW_USEDEFAULT, WinAPI::CW_USEDEFAULT, | |
rect.right - rect.left, rect.bottom - rect.top, | |
0, 0, hInstance, 0 ); | |
# カーソル設定 | |
WinAPI::SetCursor(WinAPI::LoadCursorA(0, WinAPI::IDC_ARROW)) | |
hButtonWnd = WinAPI::CreateWindowExA(0, "BUTTON", "Button Test1", | |
WinAPI::WS_VISIBLE | WinAPI::WS_CHILD | WinAPI::BS_PUSHBUTTON | WinAPI::WS_TABSTOP, | |
20, 20, | |
100, 30, | |
hWnd, 0, hInstance, 0 ); | |
hButtonWnd = WinAPI::CreateWindowExA(0, "BUTTON", "Button Test2", | |
WinAPI::WS_VISIBLE | WinAPI::WS_CHILD | WinAPI::BS_PUSHBUTTON | WinAPI::WS_TABSTOP, | |
20, 80, | |
100, 30, | |
hWnd, 0, hInstance, 0 ); | |
# ウィンドウメッセージ構造体作成 | |
msg = WinAPI::MSG.malloc | |
# メッセージループ | |
loop do | |
if WinAPI::GetMessageA(msg, 0, 0, 0) == 0 | |
break | |
end | |
WinAPI::TranslateMessage(msg) | |
WinAPI::DispatchMessageA(msg) | |
end | |
WinAPI::ReleaseActCtx(hActCtx) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment