www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - porting Windows C++ to D, a few questions

reply BLS <nanali nospam-wanadoo.fr> writes:
Hi,

I have/would like to translate a Windows C++ source into D and I have 
questions regarding
Class pointer, casting, and CALLBACK

Okay, here a C++ fragment.
class CWin : public CMsg
{

WNDCLASSEX	wcex;
wcex.hbrBackground= (HBRUSH) (COLOR_BTNFACE+1);
// How to translate this into D ?
// I guess :

//wcex.hbrBackground = cast(HBRUSH) (COLOR_BTNFACE+1);
// Is this correct ????


//Later :
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
LPARAM lParam)
// Actually I have no idea how to convert this construct into D...
{

   CWin* pWnd=NULL;
   // I think in D using a pointer to a class is not nessesary.
   // Do you agree ? However the next pb. I have is here :

pWnd = 
reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams);

// Now it seems to become difficult. In case that I define
CWin pWind; // instead off CWin* pWnd;
//then casting is impossible. So what can I do ?
}
}
Bjoern
Sep 17 2007
next sibling parent BLS <nanali nospam-wanadoo.fr> writes:
BLS schrieb:
 Hi,
 
 I have/would like to translate a Windows C++ source into D and I have 
 questions regarding
 Class pointer, casting, and CALLBACK
 
 Okay, here a C++ fragment.
 class CWin : public CMsg
 {
 
 WNDCLASSEX    wcex;
 wcex.hbrBackground= (HBRUSH) (COLOR_BTNFACE+1);
 // How to translate this into D ?
 // I guess :
 
 //wcex.hbrBackground = cast(HBRUSH) (COLOR_BTNFACE+1);
 // Is this correct ????
 
 
 //Later :
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 // Actually I have no idea how to convert this construct into D...
 {
 
   CWin* pWnd=NULL;
   // I think in D using a pointer to a class is not nessesary.
   // Do you agree ? However the next pb. I have is here :
 
 pWnd = 
 reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams);
 
 // Now it seems to become difficult. In case that I define
 CWin pWind; // instead off CWin* pWnd;
 //then casting is impossible. So what can I do ?
 }
 }
 Bjoern

The LPCREATESTRUCT from WinUser.d struct CREATESTRUCTA { LPVOID lpCreateParams; HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; int cy; int cx; int y; int x; LONG style; LPCSTR lpszName; LPCSTR lpszClass; DWORD dwExStyle; } alias CREATESTRUCTA* LPCREATESTRUCTA;
Sep 17 2007
prev sibling parent reply Regan Heath <regan netmail.co.nz> writes:
BLS wrote:
 Hi,
 
 I have/would like to translate a Windows C++ source into D and I have 
 questions regarding
 Class pointer, casting, and CALLBACK
 
 Okay, here a C++ fragment.
 class CWin : public CMsg

Don't need 'public' in there.
 {
 
 WNDCLASSEX    wcex;
 wcex.hbrBackground= (HBRUSH) (COLOR_BTNFACE+1);
 // How to translate this into D ?
 // I guess :
 
 //wcex.hbrBackground = cast(HBRUSH) (COLOR_BTNFACE+1);
 // Is this correct ????

It looks correct to me.
 //Later :
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 // Actually I have no idea how to convert this construct into D...

By including std.c.windows.windows you will get most of HWND, etc defined for you, so you can just leave them there. If you're: 1. re-writing this in D then "CALLBACK" can be removed (as it resolves to __stdcall which is not needed in D) 2. Trying to call this D function from a C application then you need to remove CALLBACK and place extern(Windows) on the front of it, i.e. extern(Windows) LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam) 3. Likewise if you're trying to call a C function from D you need to define it as #2
 {
 
   CWin* pWnd=NULL;
   // I think in D using a pointer to a class is not nessesary.
   // Do you agree ? However the next pb. I have is here :

Yes. Change this to "CWin pWnd = null;". Classes are automatically "by reference" (which is like a pointer)
 pWnd = 
 reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams);

Change this to: pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam)->lpCreateParams; You could put a cast(int) in there (where the (long) was) but I don't believe you need it. The reason you would use 'int' and not 'long' is that long in C++ is typically 32 bits and long in D is 64 bits. I'm not 100% certain that it is guaranteed to work if you cast class references to void and back again. Someone else might be able to confirm/deny this for us. Note: LPVOID is defined as void* in D
 // Now it seems to become difficult. In case that I define
 CWin pWind; // instead off CWin* pWnd;
 //then casting is impossible. So what can I do ?

Hope I got that all correct. Regan
Sep 17 2007
parent reply BLS <nanali nospam-wanadoo.fr> writes:
Regan Heath schrieb:
 BLS wrote:
 Hi,

 I have/would like to translate a Windows C++ source into D and I have 
 questions regarding
 Class pointer, casting, and CALLBACK

 Okay, here a C++ fragment.
 class CWin : public CMsg

Don't need 'public' in there.
 {

 WNDCLASSEX    wcex;
 wcex.hbrBackground= (HBRUSH) (COLOR_BTNFACE+1);
 // How to translate this into D ?
 // I guess :

 //wcex.hbrBackground = cast(HBRUSH) (COLOR_BTNFACE+1);
 // Is this correct ????

It looks correct to me.
 //Later :
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 // Actually I have no idea how to convert this construct into D...

By including std.c.windows.windows you will get most of HWND, etc defined for you, so you can just leave them there. If you're: 1. re-writing this in D then "CALLBACK" can be removed (as it resolves to __stdcall which is not needed in D) 2. Trying to call this D function from a C application then you need to remove CALLBACK and place extern(Windows) on the front of it, i.e. extern(Windows) LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam) 3. Likewise if you're trying to call a C function from D you need to define it as #2
 {

   CWin* pWnd=NULL;
   // I think in D using a pointer to a class is not nessesary.
   // Do you agree ? However the next pb. I have is here :

Yes. Change this to "CWin pWnd = null;". Classes are automatically "by reference" (which is like a pointer)
 pWnd = 
 reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams);

Change this to: pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam)->lpCreateParams; You could put a cast(int) in there (where the (long) was) but I don't believe you need it. The reason you would use 'int' and not 'long' is that long in C++ is typically 32 bits and long in D is 64 bits. I'm not 100% certain that it is guaranteed to work if you cast class references to void and back again. Someone else might be able to confirm/deny this for us. Note: LPVOID is defined as void* in D
 // Now it seems to become difficult. In case that I define
 CWin pWind; // instead off CWin* pWnd;
 //then casting is impossible. So what can I do ?

Hope I got that all correct. Regan

 Change this to:

 pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam)->lpCreateParams;

It is the ->lpCreateParams which makes me wonder..
Sep 17 2007
parent Regan Heath <regan netmail.co.nz> writes:
BLS wrote:
 Regan Heath schrieb:
 BLS wrote:
 Hi,

 I have/would like to translate a Windows C++ source into D and I have 
 questions regarding
 Class pointer, casting, and CALLBACK

 Okay, here a C++ fragment.
 class CWin : public CMsg

Don't need 'public' in there.
 {

 WNDCLASSEX    wcex;
 wcex.hbrBackground= (HBRUSH) (COLOR_BTNFACE+1);
 // How to translate this into D ?
 // I guess :

 //wcex.hbrBackground = cast(HBRUSH) (COLOR_BTNFACE+1);
 // Is this correct ????

It looks correct to me.
 //Later :
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uID, WPARAM wParam, 
 LPARAM lParam)
 // Actually I have no idea how to convert this construct into D...

By including std.c.windows.windows you will get most of HWND, etc defined for you, so you can just leave them there. If you're: 1. re-writing this in D then "CALLBACK" can be removed (as it resolves to __stdcall which is not needed in D) 2. Trying to call this D function from a C application then you need to remove CALLBACK and place extern(Windows) on the front of it, i.e. extern(Windows) LRESULT WndProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam) 3. Likewise if you're trying to call a C function from D you need to define it as #2
 {

   CWin* pWnd=NULL;
   // I think in D using a pointer to a class is not nessesary.
   // Do you agree ? However the next pb. I have is here :

Yes. Change this to "CWin pWnd = null;". Classes are automatically "by reference" (which is like a pointer)
 pWnd = 
 reinterpret_cast<CWin*>((long)((LPCREATESTRUCT)lParam)->lpCreateParams);

Change this to: pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam)->lpCreateParams; You could put a cast(int) in there (where the (long) was) but I don't believe you need it. The reason you would use 'int' and not 'long' is that long in C++ is typically 32 bits and long in D is 64 bits. I'm not 100% certain that it is guaranteed to work if you cast class references to void and back again. Someone else might be able to confirm/deny this for us. Note: LPVOID is defined as void* in D
 // Now it seems to become difficult. In case that I define
 CWin pWind; // instead off CWin* pWnd;
 //then casting is impossible. So what can I do ?

Hope I got that all correct. Regan

> Change this to: > > pWnd = cast(CWin)(cast(LPCREATESTRUCT)lParam)->lpCreateParams; It is the ->lpCreateParams which makes me wonder..

Doh! Change -> to . :) Regan
Sep 17 2007