Outils permettant d'effectuer des imprimes écran en jpeg (par hook clavier), avec tray icone.
Fonctionnalités:
- Imprime Ecran
- Compression de DC en JPEG (lib libjpeg)
- Les fichiers sont créés en local de l'application avec pour nom la date et heure local :)
- Hook clavier sans DLL (je sais beaucoup moins performant mais largement suffisant ici)
- Tray Icone (avec recréation du tray icone si l'exploreur est tué + recréé)
- Popup sur tray icone
Certains morceaux de codes viennent du site :p
Exe dans l'archive, renommer le fichier ImpScreen_V01.ex en ImpScreen_V01.exe
Source / Exemple :
//------------------------------------------------------------------------------
// Projet ImprScreen : Sauvegarde auto des imprecran en jpg
// Auteur : Hanteville Nicolas
// Fichier : main.c
// Version : 0.2
// Date de modification : 11/02/2008
//------------------------------------------------------------------------------
#include "ressources.h"
//******************************************************************************
HHOOK HHook; // Handle du hook global
char EmplacementAppli[MAX_PATH];
UINT WM_TASKBARCREATED; //gestion appel
NOTIFYICONDATA TrayIcon; //tray icone
HICON Hicon; //icone de l'application
HINSTANCE Hinst;
//******************************************************************************
//fcts de traitement pour conversion direct du hdc/BMP en jpeg
//******************************************************************************
BOOL FillJpegBuffer(LPBYTE pBits,LPBITMAPINFOHEADER pbmih, int nSampsPerRow,JSAMPARRAY jsmpPixels )
{
if (pBits == NULL || nSampsPerRow <= 0) return 0;
int r=0, p=0, q=0, nUnused=0, nBytesWide=0, nRow=0, nPixel=0;
nBytesWide = (pbmih->biWidth*3);
nUnused = (((nBytesWide + 3) / 4) * 4) - nBytesWide;
nBytesWide += nUnused;
for (r=0;r<pbmih->biHeight;r++)
{
for (p=0,q=0;p < (nBytesWide-nUnused); p+=3,q+=3)
{
nRow = (pbmih->biHeight-r-1) * nBytesWide;
nPixel = nRow + p;
jsmpPixels[r][q+0] = pBits[nPixel+2]; //Red
jsmpPixels[r][q+1] = pBits[nPixel+1]; //Green
jsmpPixels[r][q+2] = pBits[nPixel+0]; //Blue
}
}
return 1;
}
BOOL JpegFromDib(LPBYTE pBits, LPBITMAPINFOHEADER pbmih,int nQuality/*1-100*/,char *pathJpeg)
{
if (nQuality < 0 || nQuality > 100 || pBits == NULL || pathJpeg == "")return 0;
//utilise la libjpeg pour écrire les scanlines sur le disque
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE* pOutFile; //fichier cible
int nSampsPerRow; //longueur d'une ligne dans le buffer
JSAMPARRAY jsmpArray; //buffer des pixels RGB pour le fichier jpeg
cinfo.err = jpeg_std_error(&jerr); //utilisation du default error handling
jpeg_create_compress(&cinfo);
if ((pOutFile = fopen(pathJpeg, "wb")) == NULL)
{
jpeg_destroy_compress(&cinfo);
return FALSE;
}
jpeg_stdio_dest(&cinfo, pOutFile);
cinfo.image_width = pbmih->biWidth; //Image width and height, in pixels
cinfo.image_height = pbmih->biHeight;
cinfo.input_components = 3; //Color components per pixel
cinfo.in_color_space = JCS_RGB; //Colorspace of input image
jpeg_set_defaults(&cinfo); //set defaults parameters in cinfo
jpeg_set_quality(&cinfo, nQuality,1);
jpeg_start_compress(&cinfo, TRUE);
nSampsPerRow = cinfo.image_width * cinfo.input_components;
jsmpArray = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo,JPOOL_IMAGE,nSampsPerRow,cinfo.image_height);
if (FillJpegBuffer(pBits,pbmih,nSampsPerRow,jsmpArray)) jpeg_write_scanlines(&cinfo,jsmpArray,cinfo.image_height);
jpeg_finish_compress(&cinfo);
fclose(pOutFile);
jpeg_destroy_compress(&cinfo);
return TRUE;
}
//******************************************************************************
//Thread de récupération de l'heure
//récupération de l'imprime écran
//conversion
//******************************************************************************
DWORD WINAPI ImpEcran(LPVOID lParam)
{
BOOL ImprScreenActive = lParam;
char fic[MAX_PATH]="test";
unsigned short taille_Nom_Fic = 0;
//récupération de la date actuelle
time_t dateEtHMs;
time(&dateEtHMs);
//EmplacementAppli;
snprintf(fic,MAX_PATH,"%s%s",EmplacementAppli,(char *)ctime(&dateEtHMs));
fic[strlen(fic)-1]=0;
strncat(fic,".jpg\0",MAX_PATH);
fic[strlen(fic)-15]='h';
fic[strlen(fic)-12]='m';
HDC memDC,hDC;
HBITMAP Hbmp;
BITMAPINFO BmpInfo;
void *pBits;
DWORD Width, Height;
LPBITMAPINFOHEADER pBmpInfoHeader;
HWND HFen = 0;
RECT rec;
//imprime écran
if (ImprScreenActive)HFen=GetForegroundWindow();
if ((memDC=GetDC(HFen))!=0)
{
if ((hDC=CreateCompatibleDC(memDC))!=0)
{
if (ImprScreenActive)
{
GetClientRect(HFen,&rec);
Height = rec.bottom;
Width = rec.right;
}else
{
Height=GetDeviceCaps(memDC,VERTRES);
Width=GetDeviceCaps(memDC,HORZRES);
}
if (Height && Width)
{
//info de la strcuture du BMP
BmpInfo.bmiHeader.biSize =sizeof(BITMAPINFOHEADER);
BmpInfo.bmiHeader.biWidth =Width;
BmpInfo.bmiHeader.biHeight =Height;
BmpInfo.bmiHeader.biPlanes =1;
BmpInfo.bmiHeader.biBitCount =24;
BmpInfo.bmiHeader.biCompression =BI_RGB;
BmpInfo.bmiHeader.biSizeImage =0;
BmpInfo.bmiHeader.biSizeImage =0;
BmpInfo.bmiHeader.biXPelsPerMeter =0;
BmpInfo.bmiHeader.biYPelsPerMeter =0;
BmpInfo.bmiHeader.biClrUsed =0;
BmpInfo.bmiHeader.biClrImportant =0;
pBmpInfoHeader=&BmpInfo.bmiHeader;
if ((Hbmp = CreateDIBSection(0,&BmpInfo,DIB_RGB_COLORS,&pBits,0,0))!=0)
{
if (SelectObject(hDC,Hbmp)!=0)
{
if (BitBlt(hDC,0,0,Width,Height,memDC,0,0,SRCCOPY))
JpegFromDib(pBits,pBmpInfoHeader,75,fic);
}
free(pBits);
free(pBmpInfoHeader);
}
}
}
DeleteObject(Hbmp);
DeleteDC(memDC);
DeleteDC(hDC);
}
return 0;
};
//******************************************************************************
// Fonction de gestion du hook
// ici simulation d'injection de dll sans dll
//******************************************************************************
__declspec(dllexport) LRESULT CALLBACK HookProc ( int Format, WPARAM WParam, LPARAM LParam)
{
//si imprime écran standard
if ((Format == HC_ACTION) && (WParam == WM_KEYDOWN || WM_SYSCHAR))
{
// Structure d'info sur la touche appuyée
KBDLLHOOKSTRUCT hookstruct = *((KBDLLHOOKSTRUCT*)LParam);
if(hookstruct.vkCode==44)CreateThread(0,0,ImpEcran,0,0,0);//touche: Impr écran
else if(hookstruct.vkCode==19)CreateThread(0,0,ImpEcran,1,0,0);//touche Pause
}
// Renvoi des messages au sytème pour permettre d'autres hooks
return CallNextHookEx(HHook, Format, WParam, LParam);
}
//******************************************************************************
//récupère le répertoire courant de l'application
//******************************************************************************
void GetMyDirectory(char *path, unsigned int TAILLE)
{
char *c = path+GetModuleFileName(0, path,TAILLE);
while(*c != '\\') c--;
c++;
}
//******************************************************************************
//création des icones
void TrayCreate(HWND hwnd)
{
ZeroMemory(&TrayIcon, sizeof(NOTIFYICONDATA));
TrayIcon.cbSize = sizeof(NOTIFYICONDATA);
TrayIcon.hWnd = hwnd;
TrayIcon.uID = 0;
TrayIcon.hIcon = Hicon;
TrayIcon.uCallbackMessage = MY_WM_NOTIFYICON;
TrayIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
strcpy(TrayIcon.szTip, NOM_APPLI);
Shell_NotifyIcon(NIM_ADD,&TrayIcon);
}
//******************************************************************************
//traitement du popup
void AffichePOPUP(HWND hwnd, HINSTANCE Hinst)
{
POINT pos;
HMENU htmp,htmp2;
//on affiche le popup
if (GetCursorPos(&pos)!=0)
{
if ((htmp = LoadMenu(Hinst,"MY_POPUP"))!=0)
{
if ((htmp2 = GetSubMenu(htmp, 0))!=0)
{
SetForegroundWindow(hwnd);
TrackPopupMenuEx(htmp2, 0, pos.x, pos.y,hwnd, NULL);
DestroyMenu(htmp2);
}
DestroyMenu(htmp);
}
}
}
//******************************************************************************
//message sur la fenêtre principal
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_TASKBARCREATED)
TrayCreate(hwnd);
else if (message == MY_WM_NOTIFYICON && (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP))AffichePOPUP(hwnd,Hinst);
else if (message == WM_CREATE )
{
//gestion pour suppression de l'icone dans la barre de tache en cas de plantage explorer
WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
TrayCreate(hwnd);
}else if (message == WM_COMMAND)
{
if (LOWORD(wParam) == MSG_IMPSCREEN)CreateThread(0,0,ImpEcran,0,0,0);
else if (LOWORD(wParam) == MSG_IMPSCREENFEN)CreateThread(0,0,ImpEcran,1,0,0);
else if (LOWORD(wParam) == MSG_QUITTER)PostQuitMessage(0);
}else return DefWindowProc (hwnd, message, wParam, lParam);
return 0;
}
//******************************************************************************
//fct principale
//******************************************************************************
int WINAPI WinMain (HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nFunsterStil)
{
MSG messages; // gestion des messages
WNDCLASS winclass;
//GetParent(0);
Hicon = (HICON)LoadIcon(hThisInstance, MAKEINTRESOURCE(ID_ICON)); //icone de l'application
ZeroMemory(&winclass, sizeof(WNDCLASS));
winclass.lpszClassName = NOM_APPLI;
winclass.hInstance = Hinst = hThisInstance;
winclass.lpfnWndProc = WindowProcedure;
winclass.style = CS_HREDRAW | CS_VREDRAW;
winclass.hIcon = Hicon;
winclass.hCursor = LoadCursor (NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClass(&winclass))return 0;
CreateWindow(NOM_APPLI,NOM_APPLI,0,0,0,0,0,0,0,hThisInstance,0);
//emplacement courant de l'application
GetMyDirectory(EmplacementAppli,MAX_PATH-1);
//récupération du handle du hook
HHook = SetWindowsHookEx( WH_KEYBOARD_LL, (HOOKPROC) HookProc, hThisInstance, 0);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
//init
DestroyIcon(Hicon);
Shell_NotifyIcon(NIM_DELETE,&TrayIcon);
UnhookWindowsHookEx(HHook); // arret du hook a la fermeture
return messages.wParam;
}
Conclusion :
Si vous avez des questions ou recommandations elles sont les bienvenues :)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.