I wanted one small thing: press Win+Shift+S and get my own screenshot tool instead of Snipping Tool.
That turned into a 7,600-line Python project, and a pile of Windows internals that I couldn't find explained in one place. Here are the four that cost me the most hair.
1. RegisterHotKey can't claim Win+Shift+S
Every tutorial says to use RegisterHotKey. It works for Ctrl+Alt+D. It silently fails for Win+Shift+S, because the shell reserves that combo.
The way around it is a low-level keyboard hook (WH_KEYBOARD_LL, id 13), which sees the key before the shell does:
HOOKPROC = ctypes.WINFUNCTYPE(ctypes.c_ssize_t, ctypes.c_int,
ctypes.c_size_t, ctypes.c_ssize_t)
def cb(nCode, wParam, lParam):
if nCode == 0 and wParam in (0x100, 0x101, 0x104, 0x105):
kb = ctypes.cast(lParam, ctypes.POINTER(KBDLLHOOKSTRUCT)).contents
if kb.vkCode == 0x53 and win_down() and shift_down(): # S
u.keybd_event(0xE8, 0, 0, 0) # see below
u.keybd_event(0xE8, 0, 2, 0)
QTimer.singleShot(0, on_trigger) # hop back to the Qt thread
return 1 # swallow the key
return u.CallNextHookEx(None, nCode, wParam, lParam)
self._proc = HOOKPROC(cb) # keep a reference!
hook = u.SetWindowsHookExW(13, self._proc, k.GetModuleHandleW(None), 0)
Three gotchas worth knowing:
-
Keep a reference to the callback. If
HOOKPROC(cb)gets garbage-collected, your app crashes on the next keypress. There's no traceback, it just dies. -
Swallowing
Sisn't enough. If you eat the keypress and the user then releasesWin, Windows opens the Start menu. The fix is to inject an unassigned virtual key (0xE8) so Windows thinksWinwas used in a combo. -
Track the key-up too. If you swallow the key-down, you have to swallow its matching key-up, or apps see an orphaned release. I pulled this into a pure function (
snip_hook_decision(...)) with no ctypes in it, so it's unit-testable.
The hook only looks at the specific keys it cares about while Win+Shift are held. Nothing is logged or stored. If you ship a keyboard hook, say that in your README.
2. Keeping your own UI out of your own recording
My screen recorder has a floating control bar. Early on, every video started with the recorder recording itself, which looks amateur.
Windows 10 (2004+) has a one-line fix:
WDA_EXCLUDEFROMCAPTURE = 0x11
ctypes.windll.user32.SetWindowDisplayAffinity(int(widget.winId()),
WDA_EXCLUDEFROMCAPTURE)
The window stays visible to the user but is invisible to capture APIs. It's best-effort on older builds, so wrap it in try/except and move on.
3. System audio in Python: sounddevice can't do it
Recording the microphone is easy. Recording what the PC is playing is not. sounddevice can't do WASAPI loopback.
What worked:
| Source | Library |
|---|---|
| Microphone | sounddevice |
| System audio (loopback) | PyAudioWPatch |
| Mixing + muxing into MP4 |
imageio-ffmpeg (bundles an ffmpeg binary) |
The part that matters: don't mix in real time. I record each source to its own WAV on disk, then mix once after the take with ffmpeg's amix. Real-time mixing means two clocks drifting against each other. Post-mixing means a dropped buffer in one stream can't corrupt the other.
I also pad or trim each track to exactly the video duration before mixing, because mic and loopback streams never end at the same millisecond.
4. OCR with zero extra installs
I wanted "select text from a screenshot" without telling users to install Tesseract.
Windows 10/11 already ships an OCR engine: Windows.Media.Ocr. You can reach it from PowerShell, so Python just shells out:
subprocess.run(
["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ps1],
capture_output=True, timeout=120,
creationflags=0x08000000, # CREATE_NO_WINDOW, no console flash
)
The PowerShell script tries the user's language packs first and falls back to whatever recognizer is available. It runs in a QThread, so the UI never freezes. The result: no models to download, no 200 MB dependency, and it works offline.
Small things that made it feel finished
-
Recycle Bin, not delete.
os.removeis permanent.SHFileOperationWwithFOF_ALLOWUNDOsends files to the Recycle Bin, so "delete capture" is never scary. -
Atomic settings. Write to
settings.json.tmp, thenos.replace(). A crash mid-write can't corrupt your config. -
Single instance. A named mutex (
CreateMutexW+ check for error183) stops two copies fighting over the same global hotkeys. -
Autostart is one registry value under
HKCU\...\Run. No installer needed.
Where all this ended up
All of the above lives in ASNIPP, a screenshot tool, screen recorder and editor that sits as a small "Dynamic Island" pill at the top of your screen. The parts I'm proudest of:
- Screenshots with pen, highlighter, arrows, shapes, text and pixelate (for hiding sensitive info)
- A color picker with a magnifier loupe, and a pixel ruler
- Pin-to-screen floating captures
- Screen recording with system audio and mic, plus live drawing that gets recorded into the video
- A built-in video editor: trim, speed, reverse, color looks, fades, rotate and GIF export
- OCR on any capture
It's one 7600+ lines of python code packed into .exe, PyQt6, mss for capture and OpenCV for video. If you've ever wondered how far a python desktop app can go, it's a decent case study.
๐ [https://github.com/Akhouri-Systems/ASNIPP/releases/download/v1.0.0/ASNIPP_v1.zip]
If you've built something with ctypes and Win32, I'd love to hear what bit you. Drop it in the comments.
Top comments (24)
โค๏ธ
thanks star for comment
what about your channel?
After Diwali ๐
oh okay channel name StarDev?
Idk yet. Bro please share your github link.๐
github.com/Akhouri-Anmol-Kumar <--my personal
github.com/Akhouri-Systems <--Akhouri Systems
Thanks ๐ฅฐ
my personal ones is not updated wait let me update it ๐
yeah star now I've updated my personal ones too.
@star123 can you suggest some upgrades, changes needed in my personal readme to make it look better?
Very beautiful ๐
what?
@star123 if you want to join Akhouri Systems server then you can, currently it is not active or honestly it is dead because my goal is to first collect some top individuals in the server and then start the server 24/7 like big companyy servers are... and currently it has @effessdev, puneet kumar mishra, @nyaomaru @xulingfeng
discord.gg/Hb7Mk8vh5
Akhouri Systems is ready to welcome you ๐คฒ
@effessdev bro can you come online in discord?
Ok...
ok..
You mean youtube channel right?
yeah star wants to open a channel so I was suggesting a name, like I also love these channel stuff But I failed but seeing her trying I'm motivated to help her.
โค๏ธ
I also tried a couple of times (a guitar covers channel) but recording was too
hard without proper equipment so I gave up.
So I give up.๐ค
Good to remember how can we will solve this kind of promblems! โ๏ธ
I always fight with windows keyboard settings ( forced company laptop ) until I give up the fight. My trick: I use AutoHotkey program to redefine my keyboard to
capsLock+;=รฉcapsLock+'=รก... and so on
Because my main problem is the hungarian languge special character. In chat with my hungarian collegues I like to use full hungarian char set, but I always use english keyboard set and really hate to install multiple language keyboard set because windows do not saw which keyboard currently use, plus many program using english keyboard shortkeys. The whole question is so anoying.
Bro please change profile pic ๐ผ๏ธ ๐คฃ
You changed your profile image! Wow!! :D