Używanie funkcji zawartych w bibliotece DLL (rysowanie).

0

Zrobiłem biblioteke dll. Ma rysowac twarz;)
dll.h

 
#ifndef __DLL_H__
#define __DLL_H__

#include <windows.h>

#ifdef __cplusplus
extern "C"          
{
#endif
__declspec(dllexport)void Rysuj (HWND);     

#ifdef __cplusplus
}
#endif

#endif
 

dllmain.cpp

#include "dll.h"
#include <windows.h>

void  Rysuj(HWND hwnd){

    PAINTSTRUCT ps;
    /* Rozpoczęcie rysowania. Funkcja gwarantuje dostęp 
    do okna aktualnemu wątkowi. Parametry:
        hwnd - uchwyt do okna
        ps - tam funkcja przekazuje status wykonania */
    HDC hdc = BeginPaint( hwnd, &ps );  

/* Stworzenie odpowiedniego pędzla */
    HBRUSH hBrush = CreateSolidBrush(RGB(248,238,54));
/* Wybieramy odpowiedni pędzel */
    HBRUSH hOldBrush = (HBRUSH) SelectObject(hdc, hBrush);
/* Narysowanie kółka */
    Ellipse(hdc, 200, 50, 600, 450);
/* Zmmiana koloru pędzla */
    hBrush = CreateSolidBrush(RGB(116,78,75));
    hOldBrush = (HBRUSH) SelectObject(hdc, hBrush);
/* Narysowanie kółka */
    Ellipse(hdc, 300, 150, 340, 190);
    Ellipse(hdc, 460, 150, 500, 190);
/* Zmiana koloru pędzla */
    hBrush = CreateSolidBrush(RGB(225, 30, 30));
    hOldBrush = (HBRUSH) SelectObject(hdc, hBrush);
/* Narysowanie prostokąta */
    Rectangle(hdc, 375, 200, 425, 300);
/* Wykasowanie pędzla */
    DeleteObject(hBrush);
/* Zmiana narzędzia rysującego */ 
    HPEN hPen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
    HPEN hOldPen = (HPEN) SelectObject(hdc, hPen);
/* Narysowanie łuku */
    Arc(hdc, 300, 320, 500, 380, 300, 350, 3000, 350);
/* Wykasowanie pisaka */
    DeleteObject(hPen);
/* Zwolnienie uchwytu */    
    EndPaint( hwnd, &ps );

}

main.cpp

 #include <windows.h>
#include "Zasoby.h"


HINSTANCE g_hInstance;
HWND g_hwndMain;

HMODULE biblioteka=0;
typedef VOID (*MYPROC)(HDC hDc);

MYPROC RysujDll;


LONG CALLBACK MainWndProc( HWND hwnd, UINT message,
                           WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CLOSE:
        DestroyWindow(hwnd); //dorzuca do kolejki wm_quit jeśli dobrze pamiętam
        PostQuitMessage(0);
        return 0;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
            
        case PLIK_WYJSCIE:
            DestroyWindow(hwnd);
            PostQuitMessage(0);
            return 0;
        case PLIK_POMOC:
            MessageBox(hwnd,
                       "Prosta aplikacja okienkowa.",
                       "Okno pomocy", MB_OK | MB_ICONINFORMATION);
            return 0;
        }
        break;
    case WM_PAINT:
        PAINTSTRUCT ps;

        HDC hdc = BeginPaint(hwnd, &ps);
        biblioteka=LoadLibrary("bib.dll");
        RysujDll=(MYPROC)GetProcAddress(biblioteka,"Rysuj");
        RysujDll(hdc);
        
        EndPaint(hwnd, &ps);
 
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPTSTR lpCmdLine, int nCmdShow)
{
    
    WNDCLASS wc;               //deklaracje zmiennych do przechwywania inf o klasie okan
    MSG msg;                   // i komunikatów z okana aplikacji
    g_hInstance = hInstance;   //w GLOBALNEJ chowamy uchwyt do okna
    
    ZeroMemory(&wc, sizeof(WNDCLASS));  //zerujemy naszą zmienną klasową
    wc.style = 0;             // iustawiamy kolejne składowe
    wc.lpfnWndProc = MainWndProc;  //tu podpinamy funkcję obsługi komunikatów
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, "IKONA");   // tu naszą ikonę podpinamy
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);  //standardowy kursor
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //tło czarne
    wc.lpszMenuName = "MENU_GLOWNE";
    wc.lpszClassName = "KlasaOknaGlownego";
    RegisterClass(&wc); //rejesrtrujemy klasę w systemie 
    
    g_hwndMain = CreateWindow(  //tworzymy obiekt klasy zarejestrowanej przed chwilą i zapamiętujemy jego uchwyt
            "KlasaOknaGlownego",
            "Prosta aplikacja okienkowa",
            
            WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,
            CW_USEDEFAULT, CW_USEDEFAULT,
            CW_USEDEFAULT, CW_USEDEFAULT,
            NULL,
            NULL,
            hInstance,
            NULL
            );
    
    ShowWindow(g_hwndMain, SW_SHOW); //wyświetlamy ramkę
    UpdateWindow(g_hwndMain); //wyświetlamy obszar kliencki przy okazji rysując co mamy do narysowania
    
    while (GetMessage(&msg, NULL, 0, 0)) //pętla komunikatów , wykonuje się aż do 0 które zwraca WM_Quit
    {
        TranslateMessage(&msg); //tłumaczenie 
        DispatchMessage(&msg); //rozsyłanie (u nas tylko do głównego
    }
    
    return 0;
    
}

Okno programu sie pojawia....i nic dalej nie robi. A powinien narysowac Usmiechineta buzie....

mógłby mi ktoś powiedzieć co ja tam naknociłem....
Dziekuje za każdą podpowiedz

0

Hmm, tak na pierwszy rzut oka to to wygląda nieładnie:

void  Rysuj(HWND hwnd); // HWND
// (...)
HDC hdc = BeginPaint(hwnd, &ps);
RysujDll(hdc) // HDC

Nie powinieneś przypadkiem przekazywać hwnd jako parametr?

0
 51 C:\Documents and Settings\main.cpp cannot convert `HWND__*' to `HDC__*' in argument passing 

blad
jak zmienie

  RysujDll(hwnd);

na RysujDll(hdc);

0

odwrotnie ... jak zamienie :

RysujDll(hdc); 

na

 RysujDll(hwnd);
0

Typ w typedefie też zmień na HWND. Albo jeszcze lepiej - niech ta funkcja przyjmuje HDC i oddeleguje BeginPaint oraz EndPaint do aplikacji wywołującej tę funkcję.

0

void  Rysuj(HDC hdc){
HDC hdc = BeginPaint( hwnd, &ps );  
[.....]   
 EndPaint( hwnd, &ps );
}

przeciez przekazujemy end pain i beginPaint prze &ps

0

while (GetMessage(&msg, NULL, 0, 0)) //pętla komunikatów , wykonuje się aż do 0 które zwraca WM_Quit

powinno być

while (GetMessage(&msg, NULL, 0, 0) > 0)

bo zgodnie z dokumentacją, GetMessage może zwrócić -1 jako błąd, a wtedy twój warunek będzie spełniony (a nie powinien).

1 użytkowników online, w tym zalogowanych: 0, gości: 1