[win32][c][dev-c++] impscreen imprime ecran par hook sans dll sans mfc

Soyez le premier à donner votre avis sur cette source.

Vue 7 356 fois - Téléchargée 683 fois

Description

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++;

  • c = 0;
} //****************************************************************************** //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 :)

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
106
Date d'inscription
mardi 11 novembre 2003
Statut
Membre
Dernière intervention
11 février 2008

Super ca marche nikel et merci pour ta source.
Messages postés
240
Date d'inscription
jeudi 9 janvier 2003
Statut
Membre
Dernière intervention
22 mars 2009

Bonsoir,

ah oui j'ai oublier de mettre SetForegroundWindow ;p

je re up,

sinon il suffit de mettre

SetForegroundWindow(hwnd);

juste avant le TrackPopupMenuEx

voila :p

+
Messages postés
106
Date d'inscription
mardi 11 novembre 2003
Statut
Membre
Dernière intervention
11 février 2008

Salut

Super programme, simple, court mais trés efficace.

J'ai cependant une question :

Quand le menu popup apparait, on ne peut pas le faire disparaitre en cliquant n'importe ou ailleur sur l'écran, du coup on est obligé soit de quitter soit de faire un "imprime écran". Y aurait pas un moyen de régler ce probleme ?

++

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.