A Limitation That Works To Our Benefit
According to the MSDN documentation, "the RegisterHotKey function defines a system-wide hot key." Furthermore "the system posts the WM_HOTKEY message to the message queue of the window with which the hot key is associated." So what does that mean to you?
Whenever anything happens in Windows, messages are generated. Applications respond to these messages either by handling them or surfacing them as events for developers. That's how Notes uses Ctrl+A to select all the documents in a view, but when a user double-clicks on a document you have an event you can program. It's all about the messages, and who handles them.
In some other development environments you can create your own message handler, or hook. Notes doesn't allow you do that kind of low-level integration, and while that's frustrating for me in this case that works to our benefit! All you have to do is reset the Print Screen key so it gets directed to Notes. Notes isn't programmed to be aware of the message so it gets ignored. The end result is the Print Screen gets pressed and absolutely nothing happens.
The Code
(Declarations)
Declare Function FindWindowByClass Lib "user32" Alias "FindWindowA" (Byval lpClassName As String, Byval lpWindowName As Long) As Long
Declare Function GetTickCount Lib "kernel32" () As Long
Declare Function RegisterHotKey Lib "user32" (Byval hWnd As Long, Byval id As Long, Byval fsModifiers As Long, Byval vk As Long) As Long
Declare Function UnregisterHotKey Lib "user32" (Byval hWnd As Long, Byval id As Long) As Long
Declare Function GlobalAddAtom Lib "kernel32" Alias "GlobalAddAtomA" (Byval lpString As String) As Long
Declare Function GlobalDeleteAtom Lib "kernel32" (Byval nAtom As Long) As Long
Declare Function GetActiveWindow Lib "user32" Alias "GetActiveWindow" () As Long
Const VK_SNAPSHOT = &H2C
Const MOD_ALT = &H1
Const MOD_CONTROL = &H2
Const MOD_SHIFT = &H4
Dim g_hWnd As Long
Dim g_Print As Long
Dim g_AltPrint As Long
Dim g_CtrlPrint As Long
Dim g_ShiftPrint As Long
Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant)
'Get a handle to the Notes client window so you can tell Windows which window to hook the hotkeys to
g_hWnd = FindWindowByClass("Notes", 0)
'Register new identifiers for our custom hotkeys. GetTickCount returns a number that's based on the system clock,
' so you know it won't be duplicated.
g_Print = GlobalAddAtom(Cstr(GetTickCount))
g_AltPrint = GlobalAddAtom(Cstr(g_Print) + Cstr(GetTickCount))
g_CtrlPrint = GlobalAddAtom(Cstr(g_AltPrint) + Cstr(GetTickCount))
g_ShiftPrint = GlobalAddAtom(Cstr(g_CtrlPrint) + Cstr(GetTickCount))
'Now register the hotkeys
Call RegisterHotKey(g_hWnd, g_Print, 0&, VK_SNAPSHOT) 'PrintScreen
Call RegisterHotKey(g_hWnd, g_AltPrint, MOD_ALT, VK_SNAPSHOT) 'Alt+PrintScreen
Call RegisterHotKey(g_hWnd, g_CtrlPrint, MOD_CONTROL, VK_SNAPSHOT) 'Ctrl+PrintScreen
Call RegisterHotKey(g_hWnd, g_ShiftPrint, MOD_SHIFT, VK_SNAPSHOT) 'Shift+PrintScreen
End Sub
Sub Queryclose(Source As Notesuidocument, Continue As Variant)
'Unregister the hotkeys
Call UnregisterHotKey(g_hWnd, g_Print)
Call UnregisterHotKey(g_hWnd, g_AltPrint)
Call UnregisterHotKey(g_hWnd, g_CtrlPrint)
Call UnregisterHotKey(g_hWnd, g_ShiftPrint)
'Delete our custom entries
Call GlobalDeleteAtom(g_Print)
Call GlobalDeleteAtom(g_AltPrint)
Call GlobalDeleteAtom(g_CtrlPrint)
Call GlobalDeleteAtom(g_ShiftPrint)
End Sub
provided by Julian Robichaux at nsftools.com.
The Downside
Come on... you knew it couldn't be all good. :-) While this code in active Print Screen is disabled SYSTEM WIDE. Here I have it enabled in a form's QueryOpen, but you could do some tests, say for $KeepPrivate or check user roles, to enable it selectively. (Yes, I know end users can remove $KeepPrivate.) If I put this into production I would be nice and actually tell them that Print Screen is disabled, though. I'll leave that as an exercise for the reader.
Sources: Digital Inspiration blog
Answers.Com RegisterHotKey sample
vbAccelerator clsRegHotKey
[Update 5/16/08 - Removed two unused constants]
huh. that's pretty cool. doesn't defeat my camera though. ;-)
ReplyDeleteNo, it doesn't, and there are a few other techniques someone could use to clip the screen. But it does finally lay to rest the fallacy that you can't disable Print Screen. :-p
ReplyDeleteThis is a wondeful tip. Though not a fool prof way. But it works.
ReplyDeleteOne limitation that I was able to find out that this code DOES NOT work when I preview the form from Domino Designer. If you why then do reply at
naveen472-472@yahoo.co.in
Thnx
Naveen
It will work if you preview from Domino Designer preview if you put the code in the PostOpen of the form.
ReplyDeleteI know this was i while back, but i fund it just now after searching for almost a full day.
ReplyDeleteGoogle is flooded with infromation that has got nothing to do with my searchterms, this post on the pther hand is spot on and full of information.
Thanks a million!
/Linus
You're welcome. Glad you found it useful. :-)
ReplyDeletethank you, thanku thankooo for such a wonderful tip :-) :-) ...
ReplyDeletewould u please tell me how to execute this code as I am a oracle devloper so not sure how to execute this code and make it work. Thanks in advance.
ReplyDeleteWhere are you getting stuck? I included the full code along with the exact form events you need to use.
ReplyDelete