basic clipboard monitoring working in Windows
This commit is contained in:
parent
b72469b046
commit
b6ffab3ae3
|
@ -45,6 +45,7 @@ pub fn build(b: *std.build.Builder) void {
|
||||||
if (target.getOs().tag == .windows) {
|
if (target.getOs().tag == .windows) {
|
||||||
// woah...we don't actually need libc!
|
// woah...we don't actually need libc!
|
||||||
exe.linkSystemLibrary("user32");
|
exe.linkSystemLibrary("user32");
|
||||||
|
exe.linkSystemLibrary("kernel32");
|
||||||
}
|
}
|
||||||
exe.install();
|
exe.install();
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,10 @@ extern "USER32" fn RegisterClassA(
|
||||||
lpWndClass: ?*const WNDCLASSA,
|
lpWndClass: ?*const WNDCLASSA,
|
||||||
) callconv(w.WINAPI) u16;
|
) callconv(w.WINAPI) u16;
|
||||||
|
|
||||||
|
extern "USER32" fn DestroyWindow(
|
||||||
|
hWnd: ?w.HWND,
|
||||||
|
) callconv(w.WINAPI) w.BOOL;
|
||||||
|
|
||||||
const WS_OVERLAPPEDWINDOW = WINDOW_STYLE.TILEDWINDOW;
|
const WS_OVERLAPPEDWINDOW = WINDOW_STYLE.TILEDWINDOW;
|
||||||
const CW_USEDEFAULT = @as(i32, -2147483648);
|
const CW_USEDEFAULT = @as(i32, -2147483648);
|
||||||
const BOOL = i32;
|
const BOOL = i32;
|
||||||
|
@ -270,6 +274,359 @@ extern "USER32" fn DispatchMessageA(
|
||||||
lpMsg: ?*const MSG,
|
lpMsg: ?*const MSG,
|
||||||
) callconv(w.WINAPI) LRESULT;
|
) callconv(w.WINAPI) LRESULT;
|
||||||
|
|
||||||
|
const WM_NULL = @as(u32, 0);
|
||||||
|
const WM_CREATE = @as(u32, 1);
|
||||||
|
const WM_DESTROY = @as(u32, 2);
|
||||||
|
const WM_MOVE = @as(u32, 3);
|
||||||
|
const WM_SIZE = @as(u32, 5);
|
||||||
|
const WM_ACTIVATE = @as(u32, 6);
|
||||||
|
const WA_INACTIVE = @as(u32, 0);
|
||||||
|
const WA_ACTIVE = @as(u32, 1);
|
||||||
|
const WA_CLICKACTIVE = @as(u32, 2);
|
||||||
|
const WM_SETFOCUS = @as(u32, 7);
|
||||||
|
const WM_KILLFOCUS = @as(u32, 8);
|
||||||
|
const WM_ENABLE = @as(u32, 10);
|
||||||
|
const WM_SETREDRAW = @as(u32, 11);
|
||||||
|
const WM_SETTEXT = @as(u32, 12);
|
||||||
|
const WM_GETTEXT = @as(u32, 13);
|
||||||
|
const WM_GETTEXTLENGTH = @as(u32, 14);
|
||||||
|
const WM_PAINT = @as(u32, 15);
|
||||||
|
const WM_CLOSE = @as(u32, 16);
|
||||||
|
const WM_QUERYENDSESSION = @as(u32, 17);
|
||||||
|
const WM_QUERYOPEN = @as(u32, 19);
|
||||||
|
const WM_ENDSESSION = @as(u32, 22);
|
||||||
|
const WM_QUIT = @as(u32, 18);
|
||||||
|
const WM_ERASEBKGND = @as(u32, 20);
|
||||||
|
const WM_SYSCOLORCHANGE = @as(u32, 21);
|
||||||
|
const WM_SHOWWINDOW = @as(u32, 24);
|
||||||
|
const WM_WININICHANGE = @as(u32, 26);
|
||||||
|
const WM_SETTINGCHANGE = @as(u32, 26);
|
||||||
|
const WM_DEVMODECHANGE = @as(u32, 27);
|
||||||
|
const WM_ACTIVATEAPP = @as(u32, 28);
|
||||||
|
const WM_FONTCHANGE = @as(u32, 29);
|
||||||
|
const WM_TIMECHANGE = @as(u32, 30);
|
||||||
|
const WM_CANCELMODE = @as(u32, 31);
|
||||||
|
const WM_SETCURSOR = @as(u32, 32);
|
||||||
|
const WM_MOUSEACTIVATE = @as(u32, 33);
|
||||||
|
const WM_CHILDACTIVATE = @as(u32, 34);
|
||||||
|
const WM_QUEUESYNC = @as(u32, 35);
|
||||||
|
const WM_GETMINMAXINFO = @as(u32, 36);
|
||||||
|
const WM_PAINTICON = @as(u32, 38);
|
||||||
|
const WM_ICONERASEBKGND = @as(u32, 39);
|
||||||
|
const WM_NEXTDLGCTL = @as(u32, 40);
|
||||||
|
const WM_SPOOLERSTATUS = @as(u32, 42);
|
||||||
|
const WM_DRAWITEM = @as(u32, 43);
|
||||||
|
const WM_MEASUREITEM = @as(u32, 44);
|
||||||
|
const WM_DELETEITEM = @as(u32, 45);
|
||||||
|
const WM_VKEYTOITEM = @as(u32, 46);
|
||||||
|
const WM_CHARTOITEM = @as(u32, 47);
|
||||||
|
const WM_SETFONT = @as(u32, 48);
|
||||||
|
const WM_GETFONT = @as(u32, 49);
|
||||||
|
const WM_SETHOTKEY = @as(u32, 50);
|
||||||
|
const WM_GETHOTKEY = @as(u32, 51);
|
||||||
|
const WM_QUERYDRAGICON = @as(u32, 55);
|
||||||
|
const WM_COMPAREITEM = @as(u32, 57);
|
||||||
|
const WM_GETOBJECT = @as(u32, 61);
|
||||||
|
const WM_COMPACTING = @as(u32, 65);
|
||||||
|
const WM_COMMNOTIFY = @as(u32, 68);
|
||||||
|
const WM_WINDOWPOSCHANGING = @as(u32, 70);
|
||||||
|
const WM_WINDOWPOSCHANGED = @as(u32, 71);
|
||||||
|
const WM_POWER = @as(u32, 72);
|
||||||
|
|
||||||
|
const WM_COMMAND = @as(u32, 273);
|
||||||
|
const WM_INITMENU = @as(u32, 278);
|
||||||
|
const WM_INITMENUPOPUP = @as(u32, 279);
|
||||||
|
|
||||||
|
const WM_DRAWCLIPBOARD = @as(u32, 776);
|
||||||
|
const WM_SIZECLIPBOARD = @as(u32, 779);
|
||||||
|
const WM_CHANGECBCHAIN = @as(u32, 781);
|
||||||
|
|
||||||
|
const RECT = extern struct {
|
||||||
|
left: i32,
|
||||||
|
top: i32,
|
||||||
|
right: i32,
|
||||||
|
bottom: i32,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "USER32" fn GetClientRect(
|
||||||
|
hWnd: ?w.HWND,
|
||||||
|
lpRect: ?*RECT,
|
||||||
|
) callconv(w.WINAPI) BOOL;
|
||||||
|
|
||||||
|
extern "USER32" fn SendMessageA(
|
||||||
|
hWnd: ?w.HWND,
|
||||||
|
Msg: u32,
|
||||||
|
wParam: w.WPARAM,
|
||||||
|
lParam: w.LPARAM,
|
||||||
|
) callconv(w.WINAPI) LRESULT;
|
||||||
|
|
||||||
|
extern "USER32" fn DefWindowProcA(
|
||||||
|
hWnd: ?w.HWND,
|
||||||
|
Msg: u32,
|
||||||
|
wParam: w.WPARAM,
|
||||||
|
lParam: w.LPARAM,
|
||||||
|
) callconv(w.WINAPI) LRESULT;
|
||||||
|
|
||||||
|
// GDI
|
||||||
|
const HDC = *opaque {};
|
||||||
|
|
||||||
|
pub const PAINTSTRUCT = extern struct {
|
||||||
|
hdc: ?HDC,
|
||||||
|
fErase: BOOL,
|
||||||
|
rcPaint: RECT,
|
||||||
|
fRestore: BOOL,
|
||||||
|
fIncUpdate: BOOL,
|
||||||
|
rgbReserved: [32]u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "USER32" fn BeginPaint(
|
||||||
|
hWnd: ?w.HWND,
|
||||||
|
lpPaint: ?*PAINTSTRUCT,
|
||||||
|
) callconv(w.WINAPI) ?HDC;
|
||||||
|
|
||||||
|
extern "USER32" fn EndPaint(
|
||||||
|
hWnd: ?w.HWND,
|
||||||
|
lpPaint: ?*const PAINTSTRUCT,
|
||||||
|
) callconv(w.WINAPI) BOOL;
|
||||||
|
|
||||||
|
const DRAW_TEXT_FORMAT = enum(u32) {
|
||||||
|
BOTTOM = 8,
|
||||||
|
CALCRECT = 1024,
|
||||||
|
CENTER = 1,
|
||||||
|
EDITCONTROL = 8192,
|
||||||
|
END_ELLIPSIS = 32768,
|
||||||
|
EXPANDTABS = 64,
|
||||||
|
EXTERNALLEADING = 512,
|
||||||
|
HIDEPREFIX = 1048576,
|
||||||
|
INTERNAL = 4096,
|
||||||
|
LEFT = 0,
|
||||||
|
MODIFYSTRING = 65536,
|
||||||
|
NOCLIP = 256,
|
||||||
|
NOFULLWIDTHCHARBREAK = 524288,
|
||||||
|
NOPREFIX = 2048,
|
||||||
|
PATH_ELLIPSIS = 16384,
|
||||||
|
PREFIXONLY = 2097152,
|
||||||
|
RIGHT = 2,
|
||||||
|
RTLREADING = 131072,
|
||||||
|
SINGLELINE = 32,
|
||||||
|
TABSTOP = 128,
|
||||||
|
// TOP = 0, this enum value conflicts with LEFT
|
||||||
|
VCENTER = 4,
|
||||||
|
WORDBREAK = 16,
|
||||||
|
WORD_ELLIPSIS = 262144,
|
||||||
|
_,
|
||||||
|
pub fn initFlags(o: struct {
|
||||||
|
BOTTOM: u1 = 0,
|
||||||
|
CALCRECT: u1 = 0,
|
||||||
|
CENTER: u1 = 0,
|
||||||
|
EDITCONTROL: u1 = 0,
|
||||||
|
END_ELLIPSIS: u1 = 0,
|
||||||
|
EXPANDTABS: u1 = 0,
|
||||||
|
EXTERNALLEADING: u1 = 0,
|
||||||
|
HIDEPREFIX: u1 = 0,
|
||||||
|
INTERNAL: u1 = 0,
|
||||||
|
LEFT: u1 = 0,
|
||||||
|
MODIFYSTRING: u1 = 0,
|
||||||
|
NOCLIP: u1 = 0,
|
||||||
|
NOFULLWIDTHCHARBREAK: u1 = 0,
|
||||||
|
NOPREFIX: u1 = 0,
|
||||||
|
PATH_ELLIPSIS: u1 = 0,
|
||||||
|
PREFIXONLY: u1 = 0,
|
||||||
|
RIGHT: u1 = 0,
|
||||||
|
RTLREADING: u1 = 0,
|
||||||
|
SINGLELINE: u1 = 0,
|
||||||
|
TABSTOP: u1 = 0,
|
||||||
|
VCENTER: u1 = 0,
|
||||||
|
WORDBREAK: u1 = 0,
|
||||||
|
WORD_ELLIPSIS: u1 = 0,
|
||||||
|
}) DRAW_TEXT_FORMAT {
|
||||||
|
return @intToEnum(DRAW_TEXT_FORMAT, (if (o.BOTTOM == 1) @enumToInt(DRAW_TEXT_FORMAT.BOTTOM) else 0) | (if (o.CALCRECT == 1) @enumToInt(DRAW_TEXT_FORMAT.CALCRECT) else 0) | (if (o.CENTER == 1) @enumToInt(DRAW_TEXT_FORMAT.CENTER) else 0) | (if (o.EDITCONTROL == 1) @enumToInt(DRAW_TEXT_FORMAT.EDITCONTROL) else 0) | (if (o.END_ELLIPSIS == 1) @enumToInt(DRAW_TEXT_FORMAT.END_ELLIPSIS) else 0) | (if (o.EXPANDTABS == 1) @enumToInt(DRAW_TEXT_FORMAT.EXPANDTABS) else 0) | (if (o.EXTERNALLEADING == 1) @enumToInt(DRAW_TEXT_FORMAT.EXTERNALLEADING) else 0) | (if (o.HIDEPREFIX == 1) @enumToInt(DRAW_TEXT_FORMAT.HIDEPREFIX) else 0) | (if (o.INTERNAL == 1) @enumToInt(DRAW_TEXT_FORMAT.INTERNAL) else 0) | (if (o.LEFT == 1) @enumToInt(DRAW_TEXT_FORMAT.LEFT) else 0) | (if (o.MODIFYSTRING == 1) @enumToInt(DRAW_TEXT_FORMAT.MODIFYSTRING) else 0) | (if (o.NOCLIP == 1) @enumToInt(DRAW_TEXT_FORMAT.NOCLIP) else 0) | (if (o.NOFULLWIDTHCHARBREAK == 1) @enumToInt(DRAW_TEXT_FORMAT.NOFULLWIDTHCHARBREAK) else 0) | (if (o.NOPREFIX == 1) @enumToInt(DRAW_TEXT_FORMAT.NOPREFIX) else 0) | (if (o.PATH_ELLIPSIS == 1) @enumToInt(DRAW_TEXT_FORMAT.PATH_ELLIPSIS) else 0) | (if (o.PREFIXONLY == 1) @enumToInt(DRAW_TEXT_FORMAT.PREFIXONLY) else 0) | (if (o.RIGHT == 1) @enumToInt(DRAW_TEXT_FORMAT.RIGHT) else 0) | (if (o.RTLREADING == 1) @enumToInt(DRAW_TEXT_FORMAT.RTLREADING) else 0) | (if (o.SINGLELINE == 1) @enumToInt(DRAW_TEXT_FORMAT.SINGLELINE) else 0) | (if (o.TABSTOP == 1) @enumToInt(DRAW_TEXT_FORMAT.TABSTOP) else 0) | (if (o.VCENTER == 1) @enumToInt(DRAW_TEXT_FORMAT.VCENTER) else 0) | (if (o.WORDBREAK == 1) @enumToInt(DRAW_TEXT_FORMAT.WORDBREAK) else 0) | (if (o.WORD_ELLIPSIS == 1) @enumToInt(DRAW_TEXT_FORMAT.WORD_ELLIPSIS) else 0));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const DT_BOTTOM = DRAW_TEXT_FORMAT.BOTTOM;
|
||||||
|
const DT_CALCRECT = DRAW_TEXT_FORMAT.CALCRECT;
|
||||||
|
const DT_CENTER = DRAW_TEXT_FORMAT.CENTER;
|
||||||
|
const DT_EDITCONTROL = DRAW_TEXT_FORMAT.EDITCONTROL;
|
||||||
|
const DT_END_ELLIPSIS = DRAW_TEXT_FORMAT.END_ELLIPSIS;
|
||||||
|
const DT_EXPANDTABS = DRAW_TEXT_FORMAT.EXPANDTABS;
|
||||||
|
const DT_EXTERNALLEADING = DRAW_TEXT_FORMAT.EXTERNALLEADING;
|
||||||
|
const DT_HIDEPREFIX = DRAW_TEXT_FORMAT.HIDEPREFIX;
|
||||||
|
const DT_INTERNAL = DRAW_TEXT_FORMAT.INTERNAL;
|
||||||
|
const DT_LEFT = DRAW_TEXT_FORMAT.LEFT;
|
||||||
|
const DT_MODIFYSTRING = DRAW_TEXT_FORMAT.MODIFYSTRING;
|
||||||
|
const DT_NOCLIP = DRAW_TEXT_FORMAT.NOCLIP;
|
||||||
|
const DT_NOFULLWIDTHCHARBREAK = DRAW_TEXT_FORMAT.NOFULLWIDTHCHARBREAK;
|
||||||
|
const DT_NOPREFIX = DRAW_TEXT_FORMAT.NOPREFIX;
|
||||||
|
const DT_PATH_ELLIPSIS = DRAW_TEXT_FORMAT.PATH_ELLIPSIS;
|
||||||
|
const DT_PREFIXONLY = DRAW_TEXT_FORMAT.PREFIXONLY;
|
||||||
|
const DT_RIGHT = DRAW_TEXT_FORMAT.RIGHT;
|
||||||
|
const DT_RTLREADING = DRAW_TEXT_FORMAT.RTLREADING;
|
||||||
|
const DT_SINGLELINE = DRAW_TEXT_FORMAT.SINGLELINE;
|
||||||
|
const DT_TABSTOP = DRAW_TEXT_FORMAT.TABSTOP;
|
||||||
|
const DT_TOP = DRAW_TEXT_FORMAT.LEFT;
|
||||||
|
const DT_VCENTER = DRAW_TEXT_FORMAT.VCENTER;
|
||||||
|
const DT_WORDBREAK = DRAW_TEXT_FORMAT.WORDBREAK;
|
||||||
|
const DT_WORD_ELLIPSIS = DRAW_TEXT_FORMAT.WORD_ELLIPSIS;
|
||||||
|
|
||||||
|
extern "USER32" fn DrawTextA(
|
||||||
|
hdc: ?HDC,
|
||||||
|
lpchText: [*:0]const u8,
|
||||||
|
cchText: i32,
|
||||||
|
lprc: ?*RECT,
|
||||||
|
format: DRAW_TEXT_FORMAT,
|
||||||
|
) callconv(w.WINAPI) i32;
|
||||||
|
|
||||||
|
extern "USER32" fn InvalidateRect(
|
||||||
|
hWnd: ?w.HWND,
|
||||||
|
lpRect: ?*const RECT,
|
||||||
|
bErase: w.BOOL,
|
||||||
|
) callconv(w.WINAPI) BOOL;
|
||||||
|
|
||||||
|
extern "USER32" fn UpdateWindow(
|
||||||
|
hWnd: ?w.HWND,
|
||||||
|
) callconv(w.WINAPI) BOOL;
|
||||||
|
|
||||||
|
// Data exchange
|
||||||
|
extern "USER32" fn GetClipboardData(
|
||||||
|
uFormat: u32,
|
||||||
|
) callconv(w.WINAPI) ?w.HANDLE;
|
||||||
|
|
||||||
|
extern "USER32" fn GetClipboardOwner() callconv(w.WINAPI) ?w.HWND;
|
||||||
|
|
||||||
|
extern "USER32" fn SetClipboardViewer(
|
||||||
|
hWndNewViewer: ?w.HWND,
|
||||||
|
) callconv(w.WINAPI) ?w.HWND;
|
||||||
|
|
||||||
|
extern "USER32" fn OpenClipboard(
|
||||||
|
hWndNewOwner: ?w.HWND,
|
||||||
|
) callconv(w.WINAPI) BOOL;
|
||||||
|
|
||||||
|
extern "USER32" fn CloseClipboard() callconv(w.WINAPI) BOOL;
|
||||||
|
|
||||||
|
extern "USER32" fn ChangeClipboardChain(
|
||||||
|
hWndRemove: ?w.HWND,
|
||||||
|
hWndNewNext: ?w.HWND,
|
||||||
|
) callconv(w.WINAPI) BOOL;
|
||||||
|
|
||||||
|
extern "USER32" fn GetPriorityClipboardFormat(
|
||||||
|
paFormatPriorityList: [*]u32,
|
||||||
|
cFormats: i32,
|
||||||
|
) callconv(w.WINAPI) i32;
|
||||||
|
|
||||||
|
// System
|
||||||
|
extern "USER32" fn PostQuitMessage(
|
||||||
|
nExitCode: i32,
|
||||||
|
) callconv(w.WINAPI) void;
|
||||||
|
|
||||||
|
const CLIPBOARD_FORMATS = enum(u32) {
|
||||||
|
TEXT = 1,
|
||||||
|
BITMAP = 2,
|
||||||
|
METAFILEPICT = 3,
|
||||||
|
SYLK = 4,
|
||||||
|
DIF = 5,
|
||||||
|
TIFF = 6,
|
||||||
|
OEMTEXT = 7,
|
||||||
|
DIB = 8,
|
||||||
|
PALETTE = 9,
|
||||||
|
PENDATA = 10,
|
||||||
|
RIFF = 11,
|
||||||
|
WAVE = 12,
|
||||||
|
UNICODETEXT = 13,
|
||||||
|
ENHMETAFILE = 14,
|
||||||
|
HDROP = 15,
|
||||||
|
LOCALE = 16,
|
||||||
|
DIBV5 = 17,
|
||||||
|
MAX = 18,
|
||||||
|
OWNERDISPLAY = 128,
|
||||||
|
DSPTEXT = 129,
|
||||||
|
DSPBITMAP = 130,
|
||||||
|
DSPMETAFILEPICT = 131,
|
||||||
|
DSPENHMETAFILE = 142,
|
||||||
|
PRIVATEFIRST = 512,
|
||||||
|
PRIVATELAST = 767,
|
||||||
|
GDIOBJFIRST = 768,
|
||||||
|
GDIOBJLAST = 1023,
|
||||||
|
};
|
||||||
|
const CF_TEXT = CLIPBOARD_FORMATS.TEXT;
|
||||||
|
const CF_BITMAP = CLIPBOARD_FORMATS.BITMAP;
|
||||||
|
const CF_METAFILEPICT = CLIPBOARD_FORMATS.METAFILEPICT;
|
||||||
|
const CF_SYLK = CLIPBOARD_FORMATS.SYLK;
|
||||||
|
const CF_DIF = CLIPBOARD_FORMATS.DIF;
|
||||||
|
const CF_TIFF = CLIPBOARD_FORMATS.TIFF;
|
||||||
|
const CF_OEMTEXT = CLIPBOARD_FORMATS.OEMTEXT;
|
||||||
|
const CF_DIB = CLIPBOARD_FORMATS.DIB;
|
||||||
|
const CF_PALETTE = CLIPBOARD_FORMATS.PALETTE;
|
||||||
|
const CF_PENDATA = CLIPBOARD_FORMATS.PENDATA;
|
||||||
|
const CF_RIFF = CLIPBOARD_FORMATS.RIFF;
|
||||||
|
const CF_WAVE = CLIPBOARD_FORMATS.WAVE;
|
||||||
|
const CF_UNICODETEXT = CLIPBOARD_FORMATS.UNICODETEXT;
|
||||||
|
const CF_ENHMETAFILE = CLIPBOARD_FORMATS.ENHMETAFILE;
|
||||||
|
const CF_HDROP = CLIPBOARD_FORMATS.HDROP;
|
||||||
|
const CF_LOCALE = CLIPBOARD_FORMATS.LOCALE;
|
||||||
|
const CF_DIBV5 = CLIPBOARD_FORMATS.DIBV5;
|
||||||
|
const CF_MAX = CLIPBOARD_FORMATS.MAX;
|
||||||
|
const CF_OWNERDISPLAY = CLIPBOARD_FORMATS.OWNERDISPLAY;
|
||||||
|
const CF_DSPTEXT = CLIPBOARD_FORMATS.DSPTEXT;
|
||||||
|
const CF_DSPBITMAP = CLIPBOARD_FORMATS.DSPBITMAP;
|
||||||
|
const CF_DSPMETAFILEPICT = CLIPBOARD_FORMATS.DSPMETAFILEPICT;
|
||||||
|
const CF_DSPENHMETAFILE = CLIPBOARD_FORMATS.DSPENHMETAFILE;
|
||||||
|
const CF_PRIVATEFIRST = CLIPBOARD_FORMATS.PRIVATEFIRST;
|
||||||
|
const CF_PRIVATELAST = CLIPBOARD_FORMATS.PRIVATELAST;
|
||||||
|
const CF_GDIOBJFIRST = CLIPBOARD_FORMATS.GDIOBJFIRST;
|
||||||
|
const CF_GDIOBJLAST = CLIPBOARD_FORMATS.GDIOBJLAST;
|
||||||
|
|
||||||
|
// memory
|
||||||
|
extern "KERNEL32" fn GlobalUnlock(
|
||||||
|
hMem: isize,
|
||||||
|
) callconv(w.WINAPI) BOOL;
|
||||||
|
|
||||||
|
extern "KERNEL32" fn GlobalLock(
|
||||||
|
hMem: isize,
|
||||||
|
) callconv(w.WINAPI) ?*c_void;
|
||||||
|
|
||||||
|
const GLOBAL_ALLOC_FLAGS = enum(u32) {
|
||||||
|
HND = 66,
|
||||||
|
MEM_FIXED = 0,
|
||||||
|
MEM_MOVEABLE = 2,
|
||||||
|
MEM_ZEROINIT = 64,
|
||||||
|
// PTR = 64, this enum value conflicts with MEM_ZEROINIT
|
||||||
|
_,
|
||||||
|
pub fn initFlags(o: struct {
|
||||||
|
HND: u1 = 0,
|
||||||
|
MEM_FIXED: u1 = 0,
|
||||||
|
MEM_MOVEABLE: u1 = 0,
|
||||||
|
MEM_ZEROINIT: u1 = 0,
|
||||||
|
}) GLOBAL_ALLOC_FLAGS {
|
||||||
|
return @intToEnum(GLOBAL_ALLOC_FLAGS, (if (o.HND == 1) @enumToInt(GLOBAL_ALLOC_FLAGS.HND) else 0) | (if (o.MEM_FIXED == 1) @enumToInt(GLOBAL_ALLOC_FLAGS.MEM_FIXED) else 0) | (if (o.MEM_MOVEABLE == 1) @enumToInt(GLOBAL_ALLOC_FLAGS.MEM_MOVEABLE) else 0) | (if (o.MEM_ZEROINIT == 1) @enumToInt(GLOBAL_ALLOC_FLAGS.MEM_ZEROINIT) else 0));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const GHND = GLOBAL_ALLOC_FLAGS.HND;
|
||||||
|
const GMEM_FIXED = GLOBAL_ALLOC_FLAGS.MEM_FIXED;
|
||||||
|
const GMEM_MOVEABLE = GLOBAL_ALLOC_FLAGS.MEM_MOVEABLE;
|
||||||
|
const GMEM_ZEROINIT = GLOBAL_ALLOC_FLAGS.MEM_ZEROINIT;
|
||||||
|
const GPTR = GLOBAL_ALLOC_FLAGS.MEM_ZEROINIT;
|
||||||
|
|
||||||
|
extern "KERNEL32" fn GlobalAlloc(
|
||||||
|
uFlags: GLOBAL_ALLOC_FLAGS,
|
||||||
|
dwBytes: usize,
|
||||||
|
) callconv(w.WINAPI) isize;
|
||||||
|
|
||||||
|
extern "KERNEL32" fn GlobalFree(
|
||||||
|
hMem: isize,
|
||||||
|
) callconv(w.WINAPI) isize;
|
||||||
|
|
||||||
|
// resource.h
|
||||||
|
// #define IDD_MFPLAYBACK_DIALOG 102
|
||||||
|
// #define IDM_EXIT 105
|
||||||
|
// #define IDC_MFPLAYBACK 109
|
||||||
|
// #define IDD_OPENURL 129
|
||||||
|
// #define IDC_EDIT_URL 1000
|
||||||
|
// #define ID_FILE_OPENFILE 32771
|
||||||
|
// #define ID_FILE_OPENURL 32772
|
||||||
|
// #define IDC_STATIC -1
|
||||||
|
const IDM_EXIT = @as(u32, 105);
|
||||||
|
|
||||||
pub export fn wWinMain(hInstance: w.HINSTANCE, hPrevInstance: ?w.HINSTANCE, lpCmdLine: w.PWSTR, nCmdShow: w.INT) w.INT {
|
pub export fn wWinMain(hInstance: w.HINSTANCE, hPrevInstance: ?w.HINSTANCE, lpCmdLine: w.PWSTR, nCmdShow: w.INT) w.INT {
|
||||||
_ = hPrevInstance;
|
_ = hPrevInstance;
|
||||||
_ = lpCmdLine;
|
_ = lpCmdLine;
|
||||||
|
@ -338,14 +695,303 @@ pub export fn wWinMain(hInstance: w.HINSTANCE, hPrevInstance: ?w.HINSTANCE, lpCm
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
var uFormat: w.UINT = @bitReverse(c_uint, 0);
|
||||||
|
var fAuto: w.BOOL = w.TRUE;
|
||||||
|
var hwndNextViewer: ?w.HWND = null;
|
||||||
|
|
||||||
fn MainWndProc(hwnd: w.HWND, uMsg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w.WINAPI) w.LRESULT { //APIENTRY {
|
fn MainWndProc(hwnd: w.HWND, uMsg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w.WINAPI) w.LRESULT { //APIENTRY {
|
||||||
_ = hwnd;
|
// static HWND hwndNextViewer;
|
||||||
_ = uMsg; // uMsg is actually a pointer to the message
|
//
|
||||||
_ = wParam;
|
// HDC hdc;
|
||||||
_ = lParam;
|
// HDC hdcMem;
|
||||||
|
// PAINTSTRUCT ps;
|
||||||
|
// LPPAINTSTRUCT lpps;
|
||||||
|
// RECT rc;
|
||||||
|
// LPRECT lprc;
|
||||||
|
// HGLOBAL hglb;
|
||||||
|
// LPSTR lpstr;
|
||||||
|
// HBITMAP hbm;
|
||||||
|
// HENHMETAFILE hemf;
|
||||||
|
// HWND hwndOwner;
|
||||||
|
|
||||||
_ = MessageBoxA(null, "all your codebase are belong to us", "title", 0);
|
switch (uMsg) {
|
||||||
std.time.sleep(2 * std.time.ns_per_s);
|
WM_PAINT => {
|
||||||
|
var ps: PAINTSTRUCT = .{
|
||||||
|
.hdc = null,
|
||||||
|
.fErase = 0,
|
||||||
|
.rcPaint = .{
|
||||||
|
.left = 0,
|
||||||
|
.top = 0,
|
||||||
|
.right = 0,
|
||||||
|
.bottom = 0,
|
||||||
|
},
|
||||||
|
.fRestore = 0,
|
||||||
|
.fIncUpdate = 0,
|
||||||
|
.rgbReserved = [_]u8{0} ** 32,
|
||||||
|
};
|
||||||
|
var rc: RECT = .{
|
||||||
|
.left = 0,
|
||||||
|
.top = 0,
|
||||||
|
.right = 0,
|
||||||
|
.bottom = 0,
|
||||||
|
};
|
||||||
|
var hdc = BeginPaint(hwnd, &ps);
|
||||||
|
|
||||||
|
// Branch depending on the clipboard format.
|
||||||
|
switch (uFormat) {
|
||||||
|
@enumToInt(CF_OWNERDISPLAY) => {
|
||||||
|
// hwndOwner = GetClipboardOwner();
|
||||||
|
// hglb = GlobalAlloc(GMEM_MOVEABLE,
|
||||||
|
// sizeof(PAINTSTRUCT));
|
||||||
|
// lpps = GlobalLock(hglb);
|
||||||
|
// memcpy(lpps, &ps, sizeof(PAINTSTRUCT));
|
||||||
|
// GlobalUnlock(hglb);
|
||||||
|
//
|
||||||
|
// SendMessage(hwndOwner, WM_PAINTCLIPBOARD,
|
||||||
|
// (WPARAM) hwnd, (LPARAM) hglb);
|
||||||
|
//
|
||||||
|
// GlobalFree(hglb);
|
||||||
|
},
|
||||||
|
|
||||||
|
@enumToInt(CF_BITMAP) => {
|
||||||
|
// hdcMem = CreateCompatibleDC(hdc);
|
||||||
|
// if (hdcMem != NULL)
|
||||||
|
// {
|
||||||
|
// if (OpenClipboard(hwnd))
|
||||||
|
// {
|
||||||
|
// hbm = (HBITMAP)
|
||||||
|
// GetClipboardData(uFormat);
|
||||||
|
// SelectObject(hdcMem, hbm);
|
||||||
|
// GetClientRect(hwnd, &rc);
|
||||||
|
//
|
||||||
|
// BitBlt(hdc, 0, 0, rc.right, rc.bottom,
|
||||||
|
// hdcMem, 0, 0, SRCCOPY);
|
||||||
|
// CloseClipboard();
|
||||||
|
// }
|
||||||
|
// DeleteDC(hdcMem);
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
@enumToInt(CF_TEXT) => {
|
||||||
|
if (OpenClipboard(hwnd) > 0) {
|
||||||
|
var hglb = GetClipboardData(uFormat).?;
|
||||||
|
const hnd = @intCast(isize, @ptrToInt(hglb));
|
||||||
|
var lpstr = GlobalLock(hnd).?;
|
||||||
|
|
||||||
|
_ = GetClientRect(hwnd, &rc);
|
||||||
|
_ = DrawTextA(hdc, @ptrCast([*:0]const u8, lpstr), -1, &rc, DT_LEFT);
|
||||||
|
|
||||||
|
_ = GlobalUnlock(hnd);
|
||||||
|
_ = CloseClipboard();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@enumToInt(CF_ENHMETAFILE) => {
|
||||||
|
// if (OpenClipboard(hwnd))
|
||||||
|
// {
|
||||||
|
// hemf = GetClipboardData(uFormat);
|
||||||
|
// GetClientRect(hwnd, &rc);
|
||||||
|
// PlayEnhMetaFile(hdc, hemf, &rc);
|
||||||
|
// CloseClipboard();
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
0 => {
|
||||||
|
_ = GetClientRect(hwnd, &rc);
|
||||||
|
_ = DrawTextA(
|
||||||
|
hdc,
|
||||||
|
"The clipboard is empty.",
|
||||||
|
-1,
|
||||||
|
&rc,
|
||||||
|
@intToEnum(DRAW_TEXT_FORMAT, @enumToInt(DT_CENTER) | @enumToInt(DT_SINGLELINE) |
|
||||||
|
@enumToInt(DT_VCENTER)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
else => {
|
||||||
|
_ = GetClientRect(hwnd, &rc);
|
||||||
|
_ = DrawTextA(
|
||||||
|
hdc,
|
||||||
|
"Unable to display format.",
|
||||||
|
-1,
|
||||||
|
&rc,
|
||||||
|
@intToEnum(DRAW_TEXT_FORMAT, @enumToInt(DT_CENTER) | @enumToInt(DT_SINGLELINE) |
|
||||||
|
@enumToInt(DT_VCENTER)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_ = EndPaint(hwnd, &ps);
|
||||||
|
},
|
||||||
|
WM_SIZE => {
|
||||||
|
if (uFormat == @enumToInt(CF_OWNERDISPLAY)) {
|
||||||
|
var hwndOwner = GetClipboardOwner().?;
|
||||||
|
var hglb = GlobalAlloc(GMEM_MOVEABLE, @sizeOf(RECT));
|
||||||
|
defer _ = GlobalFree(hglb);
|
||||||
|
var lprc = GlobalLock(hglb);
|
||||||
|
_ = GetClientRect(hwnd, @ptrCast(?*RECT, @alignCast(@alignOf(?*RECT), lprc)));
|
||||||
|
_ = GlobalUnlock(hglb);
|
||||||
|
|
||||||
|
// hwnd and hglb are just casts
|
||||||
|
_ = SendMessageA(hwndOwner, WM_SIZECLIPBOARD, @ptrToInt(hwnd), hglb);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
WM_CREATE => {
|
||||||
|
|
||||||
|
// Add the window to the clipboard viewer chain.
|
||||||
|
|
||||||
|
hwndNextViewer = SetClipboardViewer(hwnd);
|
||||||
|
},
|
||||||
|
|
||||||
|
WM_CHANGECBCHAIN => {
|
||||||
|
|
||||||
|
// If the next window is closing, repair the chain.
|
||||||
|
|
||||||
|
// if ((HWND) wParam == hwndNextViewer)
|
||||||
|
if (wParam == @ptrToInt(hwndNextViewer.?)) {
|
||||||
|
hwndNextViewer = @intToPtr(w.HWND, @intCast(usize, lParam)); // just a cast
|
||||||
|
|
||||||
|
// Otherwise, pass the message to the next link.
|
||||||
|
|
||||||
|
} else if (hwndNextViewer) |hnv| {
|
||||||
|
_ = SendMessageA(hnv, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
WM_DESTROY => {
|
||||||
|
_ = ChangeClipboardChain(hwnd, hwndNextViewer);
|
||||||
|
PostQuitMessage(0);
|
||||||
|
},
|
||||||
|
|
||||||
|
WM_DRAWCLIPBOARD => { // clipboard contents changed.
|
||||||
|
|
||||||
|
// Update the window by using Auto clipboard format.
|
||||||
|
|
||||||
|
SetAutoView(hwnd);
|
||||||
|
|
||||||
|
// Pass the message to the next window in clipboard
|
||||||
|
// viewer chain.
|
||||||
|
|
||||||
|
_ = SendMessageA(hwndNextViewer, uMsg, wParam, lParam);
|
||||||
|
},
|
||||||
|
|
||||||
|
WM_INITMENUPOPUP => {
|
||||||
|
// if (!HIWORD(lParam))
|
||||||
|
// if (lParam > 0xffffffff)
|
||||||
|
// InitMenu(hwnd, wParam); // (HMENU) wParam);
|
||||||
|
},
|
||||||
|
|
||||||
|
WM_COMMAND => {
|
||||||
|
// switch (LOWORD(wParam)) {
|
||||||
|
switch (wParam & 0xffffffff) {
|
||||||
|
IDM_EXIT => _ = DestroyWindow(hwnd),
|
||||||
|
// IDM_AUTO => SetAutoView(hwnd),
|
||||||
|
else => {
|
||||||
|
fAuto = w.FALSE;
|
||||||
|
uFormat = @intCast(w.UINT, wParam & 0xffffffff); // LOWORD(wParam);
|
||||||
|
_ = InvalidateRect(hwnd, null, w.TRUE);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => return DefWindowProcA(hwnd, uMsg, wParam, lParam),
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
var auPriorityList: [4]u32 = .{
|
||||||
|
@enumToInt(CF_OWNERDISPLAY),
|
||||||
|
@enumToInt(CF_TEXT),
|
||||||
|
@enumToInt(CF_ENHMETAFILE),
|
||||||
|
@enumToInt(CF_BITMAP),
|
||||||
|
};
|
||||||
|
|
||||||
|
fn SetAutoView(hwnd: w.HWND) callconv(w.WINAPI) void {
|
||||||
|
var runtime_zero: usize = 0;
|
||||||
|
var auPriorityListSlice = auPriorityList[runtime_zero..auPriorityList.len];
|
||||||
|
uFormat = @intCast(c_uint, GetPriorityClipboardFormat(auPriorityListSlice.ptr, 4));
|
||||||
|
fAuto = w.TRUE;
|
||||||
|
|
||||||
|
_ = InvalidateRect(hwnd, null, w.TRUE);
|
||||||
|
_ = UpdateWindow(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn InitMenu(hwnd: w.HWND, hmenu: w.HMENU) callconv(w.WINAPI) void {
|
||||||
|
// // UINT uFormat;
|
||||||
|
// // char szFormatName[80];
|
||||||
|
// // LPCSTR lpFormatName;
|
||||||
|
// // UINT fuFlags;
|
||||||
|
// // UINT idMenuItem;
|
||||||
|
//
|
||||||
|
// // If a menu is not the display menu, no initialization is necessary.
|
||||||
|
//
|
||||||
|
// if (GetMenuItemID(hmenu, 0) != IDM_AUTO)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// // Delete all menu items except the first.
|
||||||
|
//
|
||||||
|
// while (GetMenuItemCount(hmenu) > 1)
|
||||||
|
// DeleteMenu(hmenu, 1, MF_BYPOSITION);
|
||||||
|
//
|
||||||
|
// // Check or uncheck the Auto menu item.
|
||||||
|
//
|
||||||
|
// if (fAuto) {
|
||||||
|
// fuFlags = MF_BYCOMMAND | MF_CHECKED;
|
||||||
|
// } else fuFlags = MF_BYCOMMAND | MF_UNCHECKED;
|
||||||
|
//
|
||||||
|
// CheckMenuItem(hmenu, IDM_AUTO, fuFlags);
|
||||||
|
//
|
||||||
|
// // If there are no clipboard formats, return.
|
||||||
|
//
|
||||||
|
// if (CountClipboardFormats() == 0)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// // Open the clipboard.
|
||||||
|
//
|
||||||
|
// if (!OpenClipboard(hwnd))
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// // Add a separator and then a menu item for each format.
|
||||||
|
//
|
||||||
|
// AppendMenu(hmenu, MF_SEPARATOR, 0, null);
|
||||||
|
// var uFormat = EnumClipboardFormats(0);
|
||||||
|
//
|
||||||
|
// while (uFormat) {
|
||||||
|
// // Call an application-defined function to get the name
|
||||||
|
// // of the clipboard format.
|
||||||
|
//
|
||||||
|
// var lpFormatName = GetPredefinedClipboardFormatName(uFormat);
|
||||||
|
//
|
||||||
|
// // For registered formats, get the registered name.
|
||||||
|
//
|
||||||
|
// if (lpFormatName == null) {
|
||||||
|
//
|
||||||
|
// // Note that, if the format name is larger than the
|
||||||
|
// // buffer, it is truncated.
|
||||||
|
// if (GetClipboardFormatName(uFormat, szFormatName, @sizeOf(szFormatName))) {
|
||||||
|
// lpFormatName = szFormatName;
|
||||||
|
// } else lpFormatName = "(unknown)";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Add a menu item for the format. For displayable
|
||||||
|
// // formats, use the format ID for the menu ID.
|
||||||
|
//
|
||||||
|
// if (IsDisplayableFormat(uFormat)) {
|
||||||
|
// fuFlags = MF_STRING;
|
||||||
|
// idMenuItem = uFormat;
|
||||||
|
// } else {
|
||||||
|
// fuFlags = MF_STRING | MF_GRAYED;
|
||||||
|
// idMenuItem = 0;
|
||||||
|
// }
|
||||||
|
// AppendMenu(hmenu, fuFlags, idMenuItem, lpFormatName);
|
||||||
|
//
|
||||||
|
// uFormat = EnumClipboardFormats(uFormat);
|
||||||
|
// }
|
||||||
|
// CloseClipboard();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn IsDisplayableFormat(ufmt: w.UINT) callconv(w.WINAPI) w.BOOL {
|
||||||
|
// switch (ufmt) {
|
||||||
|
// CF_OWNERDISPLAY => return true,
|
||||||
|
// CF_TEXT => return true,
|
||||||
|
// CF_ENHMETAFILE => return true,
|
||||||
|
// CF_BITMAP => return true,
|
||||||
|
// else => return false,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user