[C] Charger un jpg ds une picturebox [Résolu]

Signaler
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
-
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
-
Bonjours a tous,
Est-il possible de charger dans une picturebox des images d'autre format que bmp avec les apis win32 et en C?
Si oui comment?

Neo_Fr

36 réponses

Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
20
http://brunews.com/ImagesOle.zip

Gaffe que c'est compilé en ANSI mais InitMyPathW() prépare chemin en UNICODE.

ciao...
BruNews, MVP VC++
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
12
Voici le code que j'avais l'intention de poster:

#include <windows.h>
#include <olectl.h>

void AfficheImage(char* path, HWND hwndcible)
{
    HRESULT hres;
    IPicture* pic;
    HDC hdc;
    RECT rect;
    int hauteur, largeur;
    WCHAR wpath[260];
    MultiByteToWideChar(0,0,path,-1,wpath,260);
    hres = OleLoadPicturePath(wpath, 0,0, 0, &IID_IPicture, (void**)&pic);
    hdc=GetDC(hwndcible);
    GetClientRect(hwndcible,&rect);
    hres=pic->lpVtbl->get_Width(pic,&largeur);
    hres=pic->lpVtbl->get_Height(pic,&hauteur);
    hres=pic->lpVtbl->Render(pic,hdc,0,0,rect.right,rect.bottom,0,hauteur,largeur,-hauteur,0);
    ReleaseDC(hwndcible,hdc);
    pic->lpVtbl->Release(pic);
}

BOOL WINAPI DialogPProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
    static HWND hStatic,hBouton;
    switch(message)
    {
    case WM_INITDIALOG:
        hStatic=CreateWindowEx(0,"STATIC","",WS_VISIBLE | WS_CHILD ,10,80,300,200,hDlg,0,0,0);
        hBouton=CreateWindowEx(0,"BUTTON","Afficher",WS_VISIBLE | WS_CHILD ,10,10,60,20,hDlg,0,0,0);    
        break;

    case WM_COMMAND:
        if((HWND)lParam==hBouton) AfficheImage("c:\\image.jpg",hStatic);
        break;

    case WM_CLOSE:
        EndDialog(hDlg,0);
        break;

    default:
        break;
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE prev, LPSTR cmd, int show)
{
    LPDLGTEMPLATE lpdt;
    CoInitialize(0);   
    lpdt = ( LPDLGTEMPLATE) GlobalAlloc(GPTR, 512);
    if (!lpdt) return 1;
    lpdt->style = WS_SYSMENU  | DS_CENTER ;     lpdt->x  0;    lpdt->y  0;    lpdt->cx =300; lpdt->cy = 200;
    DialogBoxIndirectParam(0,lpdt,0,(DLGPROC)DialogPProc,(LPARAM) 0);
    GlobalFree((HGLOBAL) lpdt);
    CoUninitialize();
    return 0;
}

Ici j'utilise la méthode Render() pour afficher l'image directement dans le Device Context d'un STATIC. La fonction AfficheImage() prend en paramètres le chemin de l'image et le HWND du controle sur lequel l'image sera affichée.
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
12
Salut,
Oui en utilisant l'interface COM  IPicture. Cette dernière dispose d'une méthode permettant d'afficher une image JPG, entre autres, directement dans un Device Context. C'est la méthode Render() qui prend en premier paramètre le HDC dans lequel sera affichée l'image. Cette image doit être chargée au préalable avec une fonction comme OleLoadPicturePath().
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
J'ai trouvé ce code:
int LoadAnImage(HWND hPictureBox, char* FileName)
{
WCHAR wpath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, FileName, -1, wpath, MAX_PATH);
IPicture* pPic;
OleLoadPicturePath(wpath, 0, 0, 0, IID_IPicture, (LPVOID*)&pPic);
HBITMAP hPic = NULL;
pPic->get_Handle((UINT*)&hPic);
HBITMAP hPicRet = (HBITMAP)CopyImage(hPic, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG);
pPic->Release();
SendMessage(hPictureBox, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hPicRet);
return 0;
}

Mais j'ai un probleme avec OleLoadPicturePath:
incompatible type for argument 5 of `OleLoadPicturePath'

Neo_Fr
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Ainsi que:
structure has no member named `get_Handle'
structure has no member named `Release'

Neo_Fr
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
12
Ce code est fait pour C++. Tu comptes travailler en C ?
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
oui, je travaille en c, il exixte d'autre solutions?
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
12
En C les interfaces COM sont utilisées différemment. On accède aux méthodes via la VTable de l'interface. Je vais faire un petit test de ce code en C pour voir.
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Merci beaucoup
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
12
Pour l'instant OleLoadPicturePath() refuse de fonctionner en C. Je fais:
HRESULT res;
//...
res=OleLoadPicturePath(wpath, 0, 0, 0, &IID_IPicture, (LPVOID*)&pPic);

Elle retourne 0x800c000d. Je n'ai pas encore trouvé la cause de cette erreur.
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Peut etre qu'il faut rajouter 'CoInitialize(0);' dans ton main?

Neo_Fr
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
12
J'utilise CoInitializeEx() c'est pareil ici.
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
ah ok
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
12
Je n'ai toujours pas trouvé la cause de l'erreur. Je viens de trouver ce code:
http://www.codeproject.com/bitmap/the_beauty_of_plain_c.asp
Je l'ai testé mais j'ai exactement la même erreur de retour de OleLoadPicturePath().
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Je vient de tester ca compile mais ca ne marche pas :S
hPic = GetDlgItem(hwnd, IDC_PIC);
HANDLE h = OpenGraphic("C:\\test.jpg");
DisplayGraphic(hwnd, h);
CloseImage(h);
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
20
Salut,

en C, utiliser cette syntaxe:
Pointeur->lpVtbl->Methode()

en espérant que c'est le problème.

ciao...
BruNews, MVP VC++
Messages postés
509
Date d'inscription
samedi 28 juin 2003
Statut
Membre
Dernière intervention
3 août 2010

Voici une fonction pour recuperer le handle d'un JPEG en C:

HBITMAP LoadAnImage(char* lpFileName)
{
    HBITMAP hbmp = NULL;
    HANDLE hFile;
    DWORD dwFileSize, dwRead;
    HGLOBAL hgbl;
    char * pmem;
    HRESULT hr;
   
    hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    if(hFile == INVALID_HANDLE_VALUE)
        return NULL;
   
    dwFileSize = GetFileSize(hFile, 0);
    hgbl =(HGLOBAL)GlobalAlloc(GMEM_FIXED, dwFileSize);
   
    if(ReadFile(hFile, hgbl, dwFileSize, &dwRead, 0) && dwRead == dwFileSize)
    {
        CoInitialize(NULL);
        IStream* stream;
        hr = CreateStreamOnHGlobal(hgbl, TRUE, &stream);
        if(SUCCEEDED(hr) && stream)
        {
            IPicture* picture;
            hr = OleLoadPicture(stream, dwFileSize, 0, &IID_IPicture, (void**)&picture);
            if(SUCCEEDED(hr) && picture)
            {
                HBITMAP hsrc;
                
                picture->lpVtbl->get_Handle(picture,(OLE_HANDLE *)&hsrc);
                hbmp = (HBITMAP)CopyImage(hsrc, IMAGE_BITMAP, 0, 0, 0);
                picture->lpVtbl->Release(picture);
            }
            
            stream->lpVtbl->Release(stream);
        }
        CoUninitialize();
    }
   
    GlobalFree(hgbl);
    CloseHandle(hFile);
   
    return hbmp;
}
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Comment on fait pour l'envoyer dans un picturebox?
J'ai essayer ca:

hPic = GetDlgItem(hwnd, IDC_PIC);
HBITMAP hRET = LoadAnImage("C:\\arc.jpg");
SendMessage(hPic, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hRET);

Mais ca marche pas

Neo_Fr
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
12
BruNews >> J'ai déjà précisé à l'auteur de la question qu'il faut passer par la Vtable pour accéder aux méthodes de l'interface IPicture. J'avais l'intention de lui fournir un exemple fonctionnel en C. Mais, à ma surprise, OleLoadPicrurePath() refuse de fonctionner en C sans pouvoir en trouver la raison. Je vais essayer avec OleLoadPicture() en espérant que celle-ci marchera en C.
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
20
Je vais tester.

ciao...
BruNews, MVP VC++