Hotkey + Print

Grüß Sie,

ich brauche ein simples Programm das auf Tastendruck (z.B. die „Druck“ Taste) den aktuellen Bildschirminhalt ausdruckt.

Nun habe ich schon ein Codesample für Hotkeys und eins für Bildschirmdrucke gefunden, doch es ist mir nicht möglich diese zwei funktionell zu verbinden.

Weiß irgenwer von euch da eine Lösung? Auf Wunsch/Anfrage kann ich auch die zwei Samplecodes per Email verschicken (Virenfrei!)

Für eure Hilfe wäre ich euch sehr dankbar!!!

poste mal den code

poste mal den code - hier bitte…

Modulcode für Screencapturing:

Option Explicit
' Example usage :
'
' Set Picture1.Picture = CaptureForm(Me)
' PrintPicture Printer, Picture2.Picture
' Printer.EndDoc
'
' or :
'
' Dim oPic As StdPicture
'
' Set oPic = CaptureWindow(0, 0, 0, \_
' Screen.Width / Screen.TwipsPerPixelX, \_
' Screen.Height / Screen.TwipsPerPixelY)
'
'
Option Base 0

Private Type PALETTEENTRY
 peRed As Byte
 peGreen As Byte
 peBlue As Byte
 peFlags As Byte
End Type

Private Type LOGPALETTE
 palVersion As Integer
 palNumEntries As Integer
 'Enough for 256 colors
 palPalEntry(255) As PALETTEENTRY
End Type

Private Type GUID
 Data1 As Long
 Data2 As Integer
 Data3 As Integer
 Data4(7) As Byte
End Type


Private Const RASTERCAPS As Long = 38
Private Const RC\_PALETTE As Long = &H100
Private Const SIZEPALETTE As Long = 104

Private Type RECT
 Left As Long
 Top As Long
 Right As Long
 Bottom As Long
End Type

Private Type PicBmp
 Size As Long
 bitMapType As Long
 hBmp As Long
 hPal As Long
 Reserved As Long
End Type

Private Declare Function BitBlt Lib "GDI32" ( \_
 ByVal hDCDest As Long, ByVal XDest As Long, \_
 ByVal YDest As Long, ByVal nWidth As Long, \_
 ByVal nHeight As Long, ByVal hDCSrc As Long, \_
 ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) \_
 As Long
Private Declare Function CreateCompatibleBitmap Lib \_
 "GDI32" (ByVal hDC As Long, ByVal nWidth As Long, \_
 ByVal nHeight As Long) As Long
Private Declare Function CreateCompatibleDC Lib "GDI32" ( \_
 ByVal hDC As Long) As Long
Private Declare Function CreatePalette Lib "GDI32" ( \_
 lpLogPalette As LOGPALETTE) As Long
Private Declare Function DeleteDC Lib "GDI32" ( \_
 ByVal hDC As Long) As Long
Private Declare Function GetDeviceCaps Lib "GDI32" ( \_
 ByVal hDC As Long, ByVal iCapabilitiy As Long) As Long
Private Declare Function GetSystemPaletteEntries Lib \_
 "GDI32" (ByVal hDC As Long, ByVal wStartIndex As Long, \_
 ByVal wNumEntries As Long, lpPaletteEntries \_
 As PALETTEENTRY) As Long
Private Declare Function GetWindowDC Lib "USER32" ( \_
 ByVal hWnd As Long) As Long
Private Declare Function OleCreatePictureIndirect \_
 Lib "olepro32.dll" (PicDesc As PicBmp, RefIID As GUID, \_
 ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
Private Declare Function RealizePalette Lib "GDI32" ( \_
 ByVal hDC As Long) As Long
Private Declare Function ReleaseDC Lib "USER32" ( \_
 ByVal hWnd As Long, ByVal hDC As Long) As Long
Private Declare Function SelectObject Lib "GDI32" ( \_
 ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function SelectPalette Lib "GDI32" ( \_
 ByVal hDC As Long, ByVal hPalette As Long, \_
 ByVal bForceBackground As Long) As Long

Public Function CaptureForm(frmSrc As Form) As Picture
 On Error GoTo ErrorRoutineErr

 'Call CaptureWindow to capture the entire form
 'given it's window
 'handle and then return the resulting Picture object
 Set CaptureForm = CaptureWindow(frmSrc.hWnd, 0, 0, \_
 frmSrc.ScaleX(frmSrc.Width, vbTwips, vbPixels), \_
 frmSrc.ScaleY(frmSrc.Height, vbTwips, vbPixels))

ErrorRoutineResume:
 Exit Function
ErrorRoutineErr:
 MsgBox "Project1.Module1.CaptureForm" & Err & Error
 Resume Next
End Function

Public Function CreateBitmapPicture(ByVal hBmp As Long, \_
 ByVal hPal As Long) As Picture

 On Error GoTo ErrorRoutineErr

 Dim r As Long
 Dim Pic As PicBmp
 'IPicture requires a reference to "Standard OLE Types"
 Dim IPic As IPicture
 Dim IID\_IDispatch As GUID

 'Fill in with IDispatch Interface ID
 With IID\_IDispatch
 .Data1 = &H20400
 .Data4(0) = &HC0
 .Data4(7) = &H46
 End With

 'Fill Pic with necessary parts
 With Pic
 'Length of structure
 .Size = Len(Pic)
 'Type of Picture (bitmap)
 .bitMapType = vbPicTypeBitmap
 'Handle to bitmap
 .hBmp = hBmp
 'Handle to palette (may be null)
 .hPal = hPal
 End With

 'Create Picture object
 r = OleCreatePictureIndirect(Pic, IID\_IDispatch, 1, IPic)

 'Return the new Picture object
 Set CreateBitmapPicture = IPic

ErrorRoutineResume:
 Exit Function
ErrorRoutineErr:
 MsgBox "Project1.Module1.CreateBitmapPicture" & Err & Error
 Resume Next
End Function

Public Function CaptureWindow(ByVal hWndSrc As Long, \_
 ByVal LeftSrc As Long, \_
 ByVal TopSrc As Long, ByVal WidthSrc As Long, \_
 ByVal HeightSrc As Long) As Picture

 On Error GoTo ErrorRoutineErr

 Dim hDCMemory As Long
 Dim hBmp As Long
 Dim hBmpPrev As Long
 Dim rc As Long
 Dim hDCSrc As Long
 Dim hPal As Long
 Dim hPalPrev As Long
 Dim RasterCapsScrn As Long
 Dim HasPaletteScrn As Long
 Dim PaletteSizeScrn As Long

 Dim LogPal As LOGPALETTE

 'get device context for the window
 hDCSrc = GetWindowDC(hWndSrc)

 'Create a memory device context for the copy process
 hDCMemory = CreateCompatibleDC(hDCSrc)
 'Create a bitmap and place it in the memory DC
 hBmp = CreateCompatibleBitmap(hDCSrc, WidthSrc, HeightSrc)
 hBmpPrev = SelectObject(hDCMemory, hBmp)

 'get screen properties
 'Raster capabilities
 RasterCapsScrn = GetDeviceCaps(hDCSrc, RASTERCAPS)
 'Palette support
 HasPaletteScrn = RasterCapsScrn And RC\_PALETTE
 'Size of palette
 PaletteSizeScrn = GetDeviceCaps(hDCSrc, SIZEPALETTE)

 'If the screen has a palette, make a copy
 If HasPaletteScrn And (PaletteSizeScrn = 256) Then
 'Create a copy of the system palette
 LogPal.palVersion = &H300
 LogPal.palNumEntries = 256
 rc = GetSystemPaletteEntries(hDCSrc, 0, 256, \_
 LogPal.palPalEntry(0))
 hPal = CreatePalette(LogPal)
 'Select the new palette into the memory
 'DC and realize it
 hPalPrev = SelectPalette(hDCMemory, hPal, 0)
 rc = RealizePalette(hDCMemory)
 End If

 'Copy the image into the memory DC
 rc = BitBlt(hDCMemory, 0, 0, WidthSrc, HeightSrc, \_
 hDCSrc, LeftSrc, TopSrc, vbSrcCopy)

 'Remove the new copy of the on-screen image
 'hBmp = SelectObject(hDCMemory, hBmpPrev)

 'If the screen has a palette get back the palette that was
 'selected in previously
 If HasPaletteScrn And (PaletteSizeScrn = 256) Then
 hPal = SelectPalette(hDCMemory, hPalPrev, 0)
 End If

 'Release the device context resources back to the system
 rc = DeleteDC(hDCMemory)
 rc = ReleaseDC(hWndSrc, hDCSrc)

 'Call CreateBitmapPicture to create a picture
 'object from the bitmap and palette handles.
 'then return the resulting picture object.
 Set CaptureWindow = CreateBitmapPicture(hBmp, hPal)

ErrorRoutineResume:
 Exit Function
ErrorRoutineErr:
 MsgBox "CaptureWindow" & Err & Error
 Resume Next
End Function

Public Sub PrintPicture(Prn As Printer, Pic As Picture)
 On Error GoTo ErrorRoutineErr
'
' Prints out the selected picture to the printer
'
 Prn.PaintPicture Pic, 0, 0

ErrorRoutineResume:
 Exit Sub
ErrorRoutineErr:
 MsgBox "PrintPicture" & Err & Error
 Resume Next
End Sub

Modulcode für Hotkey:

Declare Function SendMessage Lib "USER32" Alias \_
 "SendMessageA" (ByVal hWnd As Long, \_
 ByVal wMsg As Long, ByVal wParam As Long, \_
 lParam As Long) As Long

Declare Function DefWindowProc Lib "USER32" \_
 Alias "DefWindowProcA" (ByVal hWnd As Long, \_
 ByVal wMsg As Long, ByVal wParam As Long, \_
 ByVal lParam As Long) As Long

Public Const WM\_SETHOTKEY = &H32
Public Const WM\_SHOWWINDOW = &H18
Public Const HK\_SHIFTA = &H141 'Shift + A
Public Const HK\_SHIFTB = &H142 'Shift + B
Public Const HK\_CONTROLA = &H241 'Strg + A
Public Const HK\_ALTP = &H450 'Alt + P

poste mal den code

Noch der Code im Formular

Private Sub Form\_Load()
'Let windows know what hotkey you want for your app.
 erg& = SendMessage(Me.hWnd, WM\_SETHOTKEY, HK\_ALTP, 0)
'Check if succesfull
 If erg& 1 Then MsgBox "Ein Fehler ist aufgetreten, ein anderer Hotkey wird benötigt!", vbOKOnly
'Tell windows what it should do, when the hotkey
'is pressed -\> show the window!
 erg& = DefWindowProc(Me.hWnd, WM\_SHOWWINDOW, 0, 0)
End Sub

Hi!

Kann leider diese Snipset nicht per Copy&amp:stuck_out_tongue_winking_eye:aste in VB laden, die CrLfs verschwinden irgendwie.

Schick mir bitte den Code per Mail!!

Sorry, Stefan.


Kein Problem, mail schon unterwegs!

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Michael!

Das Code-Snipset ist zwar interessant, aber für Dein Problem nutzlos, da es nur die „Standard“-Keys checked. Da aber die Funktionstasten Print, Roll, Pause, Win etc sehr tief im System verankert sind, kann’s problematisch werden, diese abzufangen.

Für die Aufgabe Press&amp:stuck_out_tongue_winking_eye:rint gibt’s aber schon Programme, die teilweise auch Freeware sind. Schau einfach mal bei Tucwos oder Winfiles.com nach.

Werde aber trotzdem nach einer Lösung suchen, dies mit VB lösen zu können.

VG, Stefan.

Das ist eben das Problem. Ein fertiges Programm kann ich nicht brauchen.

Da ich nicht auf die „Druck“ Taste zugreifen kann ist mir im Moment noch egal. Es muss soch mit diesen zwei Modulen möglich sein meine Anforderungen zu verwirklichen…

Ich schaff es aber einfach nicht diese zwei Module funktionell zu vereinigen.

Wäre nett wenn du dir das einmal anschaien könntest!

Danke

Lösung: Subclassing
Hi Michi!

Ich bin schon sehr, sehr nahe dran, das Problem zu lösen. Die Lösung funktioniert mal sicher mit Hilfe vonb Subclassing - soll heißen, dass Messages von Windows abgefangen werden.

Ich gebe einer bestimmten API-Funktion die zu überwachende Message (PrintScreen-Key) und die Adresse der (VB-) Funktion die gefeuert werden soll, sobald die oben erwähnte Message ankommt.

Ich hab’s schon für die Kontext-Menü-Taste (rechts zwischen WIN und STRG), für die PrintScreen bin ich noch am suchen.

Bin aber knapp dran…

Post dann die komplette Lösung!

LG, Stefan

99%-Lösung
Unter http://www.activevb-archiv.de/vb/VBtips/VBtip0411.shtml findest Du den Code, um Hotkeys zu registrieren und im Programm zu verarbeiten. Hab’s mit fast allen Tasten geschafft - nur nicht mit der Print. Da ich aber keine Zeit mehr habe, postete ich mal das.

Was ich aber noch herausgefunden habe: Der Print-Button hat was spezielles ansich, da er über WM_HOTEY zurückkommen kann (IDHOT_SNAPWINDOW oder IDHOT_SNAPDESKTOP). Am besten du lest Dich in die MFC der MSDN ein…

Stefan.

Danke für den Link und die Mühe, doch wie man Hotkeys registriert habe ich schon am Anfang gewusst (habe dir auch den Code geschickt).
Ich war nur nicht imstande die zwei Codesamples funktionell zu vereinen!!!

Wenn durch drücken des Hotkeys „Print“ die SubClass-Function „WinProc“ aufgerufen wird, darin dann die Screencapture-API-Calls ausführen.

Oder habe ich da was verpaßt?!?

Danke für den Link und die Mühe, doch wie man Hotkeys
registriert habe ich schon am Anfang gewusst (habe dir auch
den Code geschickt).
Ich war nur nicht imstande die zwei Codesamples funktionell zu
vereinen!!!