if you need "Printscreen" for your Xbase++ Application you can use
Code: Select all
FUNCTION GraSaveScreen(oSourcePS, aPos, aSize )
use Rogers
Code: Select all
FUNCTION SaveScreen2ClipBoard()
more Code for Test:
Code: Select all
#include "AppEvent.ch"
#include "Xbp.ch"
#define APPKEY_TOGGLED 2 // Missing from AppEvent.ch
#define VK_PAUSE 0x13 // Pause / Break (unless Ctrl is pressed)
#define VK_SNAPSHOT 0x2C // Print Screen
#define VK_CAPITAL 0x14 // Caps Lock
#define VK_NUMLOCK 0x90 // Num Lock key
#define VK_SCROLL 0x91 // Scroll Lock
Procedure Main()
LOCAL nKey := 0
LOCAL nEvent := xbe_None
LOCAL mp1, mp2, oXbp
? "This only works in GUI mode!"
while nEvent # xbeP_Close
nEvent := AppEvent(@mp1, @mp2, @oXbp, 50) // Refresh every half second
if nEvent # xbe_None
oXbp:HandleEvent(nEvent, mp1, mp2)
endif
if AppType() == APPTYPE_VIO .and. nEvent < 256
ShowKeysPressed(nEvent)
if nEvent == xbeK_ESC
exit
endif
else
nKey := iif(nEvent == xbeP_Keyboard, mp1, 0)
ShowKeysPressed(nKey)
if nKey == xbeK_ESC
exit
endif
endif
enddo
return
Procedure ShowKeysPressed(nKey)
DevPos(03, 0) ; DevOut('XBase++ Key Code: ' + PadR(alltrim(str(nKey)), 10))
DevPos(04, 0) ; DevOut('OEM Character : "' + chr(nKey) + '"')
DevPos(06, 0) ; DevOut('CAPS LOCK '+iif(AppKeyState(VK_CAPITAL , .t.)==APPKEY_TOGGLED,'ON ','OFF'))
DevPos(07, 0) ; DevOut('NUM LOCK '+iif(AppKeyState(VK_NUMLOCK , .t.)==APPKEY_TOGGLED,'ON ','OFF'))
DevPos(08, 0) ; DevOut('SCROLL LOCK '+iif(AppKeyState(VK_SCROLL , .t.)==APPKEY_TOGGLED,'ON ','OFF'))
DevPos(10, 0) ; DevOut('PAUSE/BREAK '+iif(AppKeyState(VK_PAUSE)==APPKEY_DOWN,'Down','Up '))
//
// Snapshot is (should be) made before Result of AppKeyState(VK_SNAPSHOT)
//
DevPos(11, 0) ; DevOut('PRINT SCREEN '+iif(AppKeyState(VK_SNAPSHOT)==APPKEY_DOWN,'Down','Up '))
DevPos(13, 0) ; DevOut('SHIFT '+iif(AppKeyState(xbeK_SHIFT)==APPKEY_DOWN, 'Down','Up '))
DevPos(14, 0) ; DevOut('CTRL '+iif(AppKeyState(xbeK_CTRL)==APPKEY_DOWN, 'Down','Up '))
DevPos(15, 0) ; DevOut('ALT '+iif(AppKeyState(xbeK_ALT)==APPKEY_DOWN,'Down','Up '))
return
"SubClass.OBJ" can be found here http://www.xbaseforum.de/viewtopic.php?f=16&t=4037
Code: Select all
#include "common.ch"
#include "appevent.ch"
#include "xbp.ch"
#include "dll.ch"
//
// für das benötigte subclass.obj
//
#pragma library("user32.lib")
// Windows-Message
#define WM_HOTKEY 0x0312
#define WM_APP 0x8000
#define VK_F10 0x79
#define MOD_ALT 0x0001
#define MOD_CONTROL 0x0002
#define MOD_SHIFT 0x0004
// ===========================================================
PROCEDURE Main()
LOCAL nEvent := 0, mp1, mp2, oXbp
LOCAL oDlg
local cMP2
oDlg := CreateDialog()
setappwindow( oDlg )
oDlg:show()
setappfocus( oDlg )
DO WHILE nEvent <> xbeP_Close
nEvent := AppEvent( @mp1, @mp2, @oXbp )
if nEvent == xbeP_User + WM_HOTKEY
/*
cMP2 := L2Bin( mp2 )
MsgBox("Hotkey " + var2char(mp1) + " " + ;
var2char( Bin2W(substr(cMP2,1,4) ) ), ;
appname() )
*/
// holt den Dialog nicht in den Vordergrund
MessageBeep( 0x40 )
Tone(1234)
else
oXbp:handleEvent( nEvent, mp1, mp2 )
endif
ENDDO
RETURN
// -----------------------------------------------------
// Keine DBEs, kein Konsolfenster
PROCEDURE DBESys() ; return
PROCEDURE AppSys() ; return
// ======================================================
FUNCTION CreateDialog()
LOCAL oDlg, aPos, aSize
LOCAL nXsize := 400
LOCAL nYsize := 100
aSize := AppDesktop():currentSize()
// zentriert
aPos := { ( aSize[1]-nXsize )/2, ( aSize[2]-nYsize ) / 2 }
oDlg := XbpHotkeyDialog():new( AppDesktop(),, aPos, {nXsize,nYsize}, , FALSE )
oDlg:title := "Hotkey-Beispiel - Alt+F10"
oDlg:taskList := .T.
oDlg:create()
RETURN oDlg
CLASS XbpHotkeyDialog FROM XbpDialog
EXPORTED:
VAR lHotkeySet
INLINE METHOD Init( oParent, oOwner, aPos, aSize, aPP, lVisible )
::lHotkeySet := .F.
::XbpDialog:Init( oParent, oOwner, aPos, aSize, aPP, lVisible )
RETURN self
INLINE METHOD Create( oParent, oOwner, aPos, aSize, aPP, lVisible )
local rc
::XbpDialog:create( oParent, oOwner, aPos, aSize, aPP, lVisible )
rc := _Subclass( ::getHWND(), {|a,b,c,d|::HotkeyHandler(a,b,c,d)} )
// Hotkey definieren. Das funktioniert nur innerhalb des EVM/GUI-Threads,
// nicht aus Anwendungs-Threads.
rc := SendMessageA( ::getHWND(), WM_APP+1, 0, 0 )
RETURN self
INLINE METHOD Configure( oParent, oOwner, aPos, aSize, aPP, lVisible )
local rc
if ::lHotkeySet
// Hotkey entfernen. Das funktioniert nur innerhalb des EVM/GUI-Threads,
// nicht aus Anwendungs-Threads.
rc := SendMessageA( ::getHWND(), WM_APP+2, 0, 0 )
endif
rc := _Unsubclass( ::getHWND() )
::XbpDialog:configure( oParent, oOwner, aPos, aSize, aPP, lVisible )
rc := _Subclass( ::getHWND(), {|a,b,c,d|::HotkeyHandler(a,b,c,d)} )
rc := SendMessageA( ::getHWND(), WM_APP+1, 0, 0 )
RETURN self
INLINE METHOD Close()
::destroy()
return self
INLINE METHOD Destroy()
local rc
if ::lHotkeySet
// Hotkey entfernen. Das funktioniert nur innerhalb des EVM/GUI-Threads,
// nicht aus Anwendungs-Threads.
rc := SendMessageA( ::getHWND(), WM_APP+2, 0, 0 )
endif
rc := _Unsubclass( ::getHWND() )
::XbpDialog:destroy()
RETURN self
// wird im EVM/GUI-Thread durch Windows aufgerufen.
INLINE METHOD HotkeyHandler( hwnd, msg, wparam, lparam )
local rc
if msg == WM_HOTKEY
// Hotkey-Event an Xbase++ weiterleiten
PostAppEvent( xbeP_User + WM_HOTKEY, wParam, lParam, self )
return 0
elseif msg == WM_APP+1
// Hotkey registrieren
if ! ::lHotkeySet
rc := RegisterHotKey( hWnd, 1234, MOD_ALT, VK_F10 )
if rc <> 0
::lHotkeySet := .T.
endif
endif
return 0
elseif msg == WM_APP+2
// Hotkey deregistrieren
if ::lHotkeySet
rc := UnregisterHotKey( hWnd, 1234 )
if rc <> 0
::lHotkeySet := .F.
endif
endif
return 0
endif
// Defaultverarbeitung aller anderen Messages.
RETURN _CallPrevWindowProc( hwnd, msg, wparam, lparam )
ENDCLASS
dllfunction RegisterHotKey(hWnd, id, nModifiers, nVKeyCode ) using stdcall from user32.dll
dllfunction UnregisterHotKey(hWnd, id) using stdcall from user32.dll
dllfunction SendMessageA(hWnd, msg, wParam, lParam ) using stdcall from user32.dll
dllfunction MessageBeep( nSoundID ) using stdcall from user32.dll
// EOF