Panowie, jesli mielibyście czas możecie sprawdzić dllkę oraz plik którym ją sprawdzam czy działa, a nastepnie wytknąć mi błąd prze który okno mi nie wyskakuje? Prawdopodobnie coś pogrzałem z wczytywaniem adresu ale nie jestem pewien. W ogóle nie wiem co jest nie tak. Pliki w załączniku
Lepiej wklej samą funkcję oraz miejsce jej wywołania, bezpośrednio.
Nie chcę mi się ściągać zip, rozpakowywać itp, może inni też mają mistrzowski poziom lenistwa.
Projekt DLL:
main.h
HWND DLL_EXPORT f_CreateButton(HINSTANCE hInstance, HWND hParent, char *sciezka, COLORREF cTransparent, int x, int y, int width, int height, int ID, DWORD flags, HRGN hRegion, void *dane);
main.cpp
HWND DLL_EXPORT f_CreateButton(HINSTANCE hInstance, HWND hParent, char *sciezka, COLORREF cTransparent, int x, int y, int width, int height, int ID, DWORD flags, HRGN hRegion, void *dane){}
Projekt test:
button.h
#include <windows.h>
#define MC_MOUSEMOVE 1
#define MC_LBDOWN 2
#define MC_LBUP 4
#define MC_RBDOWN 8
#define MC_RBUP 16
#define MC_DBCLICK 32
#define BUTTON_STYLE_LostCapture 1
#define BUTTON_STYLE_RegionCircle 2
#define BUTTON_STYLE_MyRegion 4
#define BUTTON_STYLE_SendMouseCommand 8
#define BUTTON_STAN_AKTYWNY 0
#define BUTTON_STAN_NAJECHANY 1
#define BUTTON_STAN_WCISNIETY 2
#define BUTTON_STAN_NIEAKTYWNY 3
#define BUTTON__GETID 0x8001 /// wParam == & int
#define BUTTON__GETDATA 0x8002 /// wParam == & void
#define BUTTON__SETDATA 0x8003 /// wParam == void * /// lParam == & void (stare dane)
#define BUTTON__GETFOCUS 0x8004 /// wParam == & int
#define BUTTON__SETFOCUS 0x8005 /// wParam == int
#define BUTTON__GETXY 0x8006 /// wParam == & POINT
#define BUTTON__GETWIDTH 0x8007 /// wParam == & int
#define BUTTON__GETHEIGHT 0x8008 /// wParam == & int
#define BUTTON__GETCAPTURE 0x8009 /// wParam == & bool
typedef BOOL( *RejestrujButton )( HINSTANCE );
RejestrujButton f_RejestrujButton;
typedef HWND( *CreateButton )( HINSTANCE, HWND, char*, COLORREF, int, int, int, int, int, DWORD, HRGN, void*);
CreateButton f_CreateButton;
HINSTANCE InitializeButton(HINSTANCE hInstance, LPCSTR sciezka){
HINSTANCE hDll = LoadLibrary( sciezka );
if(!hDll)
return 0;
f_RejestrujButton = (RejestrujButton)GetProcAddress( hDll, "f_RejestrujButton" );
f_CreateButton = (CreateButton)GetProcAddress( hDll, "f_CreateButton" );
f_RejestrujButton(hInstance);
return hDll;
}
main.cpp
hDll = InitializeButton(hThisInstance, "static buttons");
if(!hDll)
{
MessageBox(0, "blad", "", MB_OK);
return 0;
}
hPrzycisk = (HWND)(CreateButton)(hThisInstance,hwnd,"LEWO.bmp",RGB(0,0,0),0,0,50,50,100, 0, NULL,NULL);
Pod czym kompilujesz i jak u ciebie zadeklarowane to DLL_EXPORT
?
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
Uzywam środowiska codeblock z wbudowanym kompilatorem mingw.
EDIT:
Wybaczcie, że wcześniej tego nie zrobiłem ale chyba w nocy juz nie myślałem. Wyskoczyły mi warningi, których nie potrafię zinterpretować:
||=== Build: Release in test (compiler: GNU GCC Compiler) ===|
C:\Users\User\Desktop\test\main.cpp||In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':|
C:\Users\User\Desktop\test\main.cpp|71|warning: left operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|72|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|74|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|75|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|76|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|77|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|78|warning: right operand of comma operator has no effect [-Wunused-value]|
C:\Users\User\Desktop\test\main.cpp|79|warning: right operand of comma operator has no effect [-Wunused-value]|
||=== Build finished: 0 error(s), 8 warning(s) (0 minute(s), 0 second(s)) ===|
Czy masz zadeklarowane to BUILD_DLL przy budowie DLL?
Proste sprawdzenie, dodajesz kod do DLL:
#ifndef BUILD_DLL
#error To ma się nie skompilować bo brak __declspec(dllexport)
#endif
To jest moje całe main.h z dll
#ifndef __MAIN_H__
#define __MAIN_H__
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
/* To use this exported function of dll, include this header
* in your project.
*/
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
/*
*/
#ifdef __cplusplus
extern "C"
{
#endif
#define ERR_PUSTYWSKAZNIK 1
#define STYLE_LostCapture 1
#define STYLE_RegionCircle 2
#define STYLE_MyRegion 4
#define STYLE_SendMouseCommand 8
#define MC_MOUSEMOVE 1
#define MC_LBDOWN 2
#define MC_LBUP 4
#define MC_RBDOWN 8
#define MC_RBUP 16
#define MC_DBCLICK 32
#define STAN_AKTYWNY 0
#define STAN_NAJECHANY 1
#define STAN_WCISNIETY 2
#define STAN_NIEAKTYWNY 3
#define WH_BT_GETID 0x8001 /// wParam == & int
#define WH_BT_GETDATA 0x8002 /// wParam == & void
#define WH_BT_SETDATA 0x8003 /// wParam == void * /// lParam == & void (stare dane)
#define WH_BT_GETFOCUS 0x8004 /// wParam == & int
#define WH_BT_SETFOCUS 0x8005 /// wParam == int
#define WH_BT_GETXY 0x8006 /// wParam == & POINT
#define WH_BT_GETWIDTH 0x8007 /// wParam == & int
#define WH_BT_GETHEIGHT 0x8008 /// wParam == & int
#define WH_BT_GETCAPTURE 0x8009 /// wParam == & bool
void DLL_EXPORT ShowError(int ID);
struct DLL_EXPORT sButtonInfo{
HWND hwnd;
POINT cur;
int message;
};
struct DLL_EXPORT sButtonClassInfo{
HINSTANCE hInstance;
HWND hWindow;
HRGN hRegion;
HBITMAP hBitmap;
COLORREF cTransparent;
DWORD flagi;
void *dane;
};
class DLL_EXPORT sButtonClass{
public:
sButtonClass(struct sButtonClassInfo *wsk);
~sButtonClass();
HDC GiveMeSourceDC();
HDC GiveMeMaskSourceDC();
int GetStan();
void SetStan(int Stan);
bool GetCapture();
void SetCapture(bool Capture);
DWORD GetFlags();
int BitmapWidth();
int BitmapHeight();
int WindowWidth();
int WindowHeight();
void OdswiezOkno();
void WyslijWiadomoscDoParenta(UINT message, WPARAM wParam, LPARAM lParam);
bool KursorWewnatrz();
void WypelnijButtonInfo(struct sButtonInfo *wsk, HWND hwnd, int x, int y, int message);
void GetCoordinate(POINT *point);
int GetID();
void SetDane(void *Dane);
void *GetDane();
private:
HINSTANCE hInstance;
HWND hWindow;
HWND hParent;
HRGN hRegion;
DWORD flagi;
int nasycenie;
COLORREF cTransparent;
HBITMAP hBmpSource;
HDC hDCSource;
HBITMAP hBmpSourceMask;
HDC hDCSourceMask;
int dlugosc_bitmapy;
int wysokosc_bitmapy;
bool capture;
int stan;
void *dane;
HBITMAP CreateBitmapMask( HBITMAP hbmColour, COLORREF crTransparent );
};
LRESULT CALLBACK DLL_EXPORT ButtonProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL DLL_EXPORT f_RejestrujButton( HINSTANCE hInst );
HWND DLL_EXPORT f_CreateButton(HINSTANCE hInstance, HWND hParent, char *sciezka, COLORREF cTransparent, int x, int y, int width, int height, int ID, DWORD flags, HRGN hRegion, void *dane);
#ifdef __cplusplus
}
#endif
#endif // __MAIN_H__
Nie ma tam wzmianki o tym :(
EDIT:
Posprawdzałem, czy dll się wczytuje poprawnie i czy wskaźniki na adresy funkcji nie są zerowe i niby wszystko jest w porządku.
Zastanawiam się tylko skąd te warningi (pochodzą z wywołania funkcji CreateButton())
hPrzycisk = (HWND)(CreateButton)(
hThisInstance, /// hInstance
hwnd, /// hParent
"LEWO.bmp", /// sciezka do bmp
RGB(0,0,0), /// cTransparent
0, /// x
0, /// y
50, /// width
50, /// height
100, /// ID
0, /// flags
NULL, /// hRegion
NULL /// hDane
);
EDIT2:
Dodałem w dll w funkcji CreateButton() MessageBox'a, niestety przy wywołaniu funkcji nie pokazuje sie on, czyli funkcja w ogóle nie startuje :(
KUTFA MAM !
typedef BOOL( *RejestrujButton )( HINSTANCE );
RejestrujButton f_RejestrujButton;
typedef HWND( *CreateButton )( HINSTANCE, HWND, char*, COLORREF, int, int, int, int, int, DWORD, HRGN, void*);
CreateButton f_CreateButton;
oraz:
hPrzycisk = (HWND)(CreateButton)(
hThisInstance, /// hInstance
hwnd, /// hParent
"LEWO.bmp", /// sciezka do bmp
RGB(0,0,0), /// cTransparent
0, /// x
0, /// y
50, /// width
50, /// height
100, /// ID
0, /// flags
NULL, /// hRegion
NULL /// hDane
);
Zamiast CreateButton() powinno być f_CreateButton(). Cały dzień stracony przez to xd
Ale bez Ciebie bym nawet nie spojrzał na to, Twój ostatni komentarz mi nasunął ten pomysł ! Dziekuje ślicznie za pomoc !
Radzę w ten sposób deklarować wskaźniki na funkcji:
typedef HWND CreateButtonFunction( HINSTANCE, HWND, char*, COLORREF, int, int, int, int, int, DWORD, HRGN, void*);
CreateButtonFunction *CreateButton;
przed tym błędem zostałbyś uchroniony w postaci jaśniejszego komunikatu.
Źle robisz, że tworzysz dwa pliki nagłówkowe.
Po to się robi to #ifdef BUILD_DLL
, by ten sam nagłówek był użyty podczas kompilacji programu co podczas kompilacji DLL-ki.
@Azarien i wtedy muszę nieco zmodyfikować funkcję
HINSTANCE InitializeButton(HINSTANCE hInstance, LPCSTR sciezka);
?
W programie najpierw załadować dllkę i potem wczytać funkcję Initialize() umieszczoną w pliku nagłówkowym DLL-ki?
Wtedy funkcja ta wyglądałaby tak?
HINSTANCE InitializeButton(HINSTANCE hInstance, HINSTANCE hDll){
f_RejestrujButton = (RejestrujButtonFunction)GetProcAddress( hDll, "f_RejestrujButton" );
if(!f_RejestrujButton)
MessageBox(0, "f_RejestrujButton", "Blad pobierania procesu", MB_OK);
f_CreateButton = (CreateButtonFunction)GetProcAddress( hDll, "f_CreateButton" );
if(!f_CreateButton)
MessageBox(0, "f_CreateButton", "Blad pobierania procesu", MB_OK);
(f_RejestrujButton)(hInstance);
return hDll;
}
Ale ale... Jeżeli korzystam z pliku nagłówkowego, to chyba nie muszę już dynamicznie wczytywać funkcji? Gubię sie.