static Status sys_cursor_create_common(int w, int h, void* bgra_img, void* mask_img, int hx, int hy, sys_cursor* cursor) { *cursor = 0; // MSDN says selecting this HBITMAP into a DC is slower since we use // CreateBitmap; bpp/format must be checked against those of the DC. // this is the simplest way and we don't care about slight performance // differences because this is typically only called once. HBITMAP hbmColor = CreateBitmap(w, h, 1, 32, bgra_img); // CreateIconIndirect doesn't access this; we just need to pass // an empty bitmap. HBITMAP hbmMask = CreateBitmap(w, h, 1, 1, mask_img); // create the cursor (really an icon; they differ only in // fIcon and the hotspot definitions). ICONINFO ii; ii.fIcon = FALSE; // cursor ii.xHotspot = (DWORD)hx; ii.yHotspot = (DWORD)hy; ii.hbmMask = hbmMask; ii.hbmColor = hbmColor; HICON hIcon = CreateIconIndirect(&ii); // CreateIconIndirect makes copies, so we no longer need these. DeleteObject(hbmMask); DeleteObject(hbmColor); if(!wutil_IsValidHandle(hIcon)) WARN_RETURN(ERR::FAIL); *cursor = cursor_from_HICON(hIcon); return INFO::OK; }
void AttachToCompletionPort(HANDLE hFile, HANDLE& hIOCP, ULONG_PTR key, DWORD numConcurrentThreads) { WinScopedPreserveLastError s; // CreateIoCompletionPort // (when called for the first time, ends up creating hIOCP) hIOCP = CreateIoCompletionPort(hFile, hIOCP, key, numConcurrentThreads); ENSURE(wutil_IsValidHandle(hIOCP)); }