Translate C --> PB

Windows specific forum
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Translate C --> PB

Post by cecilcheah »

Hi all:

Thanks for all the help before. They are all working perfectly. I can now draw text on the images inside clipboard, and i can do the Hotkey as well as capture any screen i want. Shall i publish my code somewhere?

Anyway, to my question today. I was given the following C code which i need to translate to PB. Basically i need to be able to call the procedere, TB_execute(hWndOfTB, FALSE, "send paste"), inside PB. This procedere will enable me to send a command to an external programme (TB) which in turn will execute the send paste command.

Here is the C code:



Code: Select all

//
// CECIL.C
//

#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>


// needed because WM_COPYDATA isn't defined in the 16-bit Windows API Headers
//
#if !defined(WM_COPYDATA) && !defined(WIN32)

		 #define WM_COPYDATA		 0x4a // as for WIN32

		 typedef struct tagCOPYDATASTRUCT
		 {
		 		 DWORD dwData; 		 // a place to put just 32 bits of data
		 		 DWORD cbData;		 // size in bytes of data pointed to by PVOID
		 		 LPVOID lpData;		 // other data to be passed to the reciving app
		 } COPYDATASTRUCT, FAR * LPCOPYDATASTRUCT;
#endif

#if !defined(LPCOPYDATASTRUCT) && defined(WIN32)
		 typedef struct tagCOPYDATASTRUCT FAR * LPCOPYDATASTRUCT;
#endif



// This "ID" is used to implement an equivalent to TBM_EXECUTE that operates
// across 32-bit processes
//
// "lpData" is an LPCOPYDATA_EXECUTE
//
#define COPYDATA_EXECUTE		 		 (0x00000003)

typedef struct COPYDATA_EXECUTEtag
{
		 long		 bSysSuspendOff;		 		 // TRUE == sysSuspend is set to false
		 		 		 		 		 		 		 		 // during command execution
		 char		 szStatements[1];		 // A zero-terminated ASCII string containing
		 		 		 		 		 		 		 		 // the OpenScript statements to be executed.
} COPYDATA_EXECUTEDATA, FAR * LPCOPYDATA_EXECUTEDATA;



// Cecil - this function will execute a string from Pure Basic
// eg. TB_execute(hWndOfTB, FALSE, "send paste")
BOOL TB_execute( HWND hWnd, BOOL bSysSuspendOff, LPCSTR lpStatements )
{
		 BOOL		 		 		 		 		 bResult;
		 LPCOPYDATA_EXECUTEDATA		 lpExec;
		 COPYDATASTRUCT		 		 		 Data;

		 HANDLE  hStr;

		 Data.dwData = COPYDATA_EXECUTE;
		 Data.cbData = sizeof(*lpExec) + lstrlen(lpStatements) + 1;

		 hStr = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE, (DWORD)(Data.cbData));
		 if (hStr != NULL) {
		 		 lpExec = (LPCOPYDATA_EXECUTEDATA)GlobalLock(hStr);
		 		 if ( lpExec != NULL )
		 		 {
		 		     Data.lpData = lpExec;

		 		     lpExec->bSysSuspendOff = bSysSuspendOff;
		 		     lstrcpy(lpExec->szStatements, lpStatements );

		 		     bResult = ( SendMessage(		 hWnd, WM_COPYDATA,
		 		 		 		 		 		 NULL, (LPARAM)(LPVOID)&Data ) != 0 );
		 		     GlobalUnlock(hStr);
		 		 } else {
		 		     bResult		 = FALSE;
		 		 }
		 		 GlobalFree(hStr);
		 } else {
		 		 bResult		 = FALSE;
		 }

		 return bResult;
}
I am not very well educated in C, so any pointer will help me a lot.

Thanks in advance.

Cecil
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Post by cecilcheah »

OK, no one can help. Maybe my code is too overhelming.

Here is what i have translated and what i cannot.

Code: Select all

typedef struct tagCOPYDATASTRUCT
	{
		DWORD dwData; 	// a place to put just 32 bits of data
		DWORD cbData;	// size in bytes of data pointed to by PVOID
		LPVOID lpData;	// other data to be passed to the reciving app
	} COPYDATASTRUCT, FAR * LPCOPYDATASTRUCT;
to

Code: Select all

Structure COPYDATASTRUCT
  dwData.l
  cbData.l
  lpData.l
EndStructure 
Is this OK? How do I translate FAR * LPCOPYDATASTRUCT to PB?

And how do i translate the following, given what i have translated above?

Code: Select all

#if !defined(WM_COPYDATA) && !defined(WIN32)

	#define WM_COPYDATA	0x4a // as for WIN32

	typedef struct tagCOPYDATASTRUCT
	{
		DWORD dwData; 	// a place to put just 32 bits of data
		DWORD cbData;	// size in bytes of data pointed to by PVOID
		LPVOID lpData;	// other data to be passed to the reciving app
	} COPYDATASTRUCT, FAR * LPCOPYDATASTRUCT;
#endif
Here is what i have also translated:

Code: Select all

typedef struct COPYDATA_EXECUTEtag
{
	long	bSysSuspendOff;		// TRUE == sysSuspend is set to false
								// during command execution
	char	szStatements[1];	// A zero-terminated ASCII string containing
								// the Script statements to be executed.
} COPYDATA_EXECUTEDATA, FAR * LPCOPYDATA_EXECUTEDATA;
to:

Code: Select all

Structure COPYDATA_EXECUTEDATA
  bSysSuspendOff.l
  szStatements.b[1] 
EndStructure 
Is the array translation correct?

Last question is:

How do i start translating this:

Code: Select all

BOOL tb_execute( HWND hWnd, BOOL bSysSuspendOff, LPCSTR lpStatements )
Thanks again.

Cecil
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Translate C --> PB

Post by ricardo »

cecilcheah wrote:Shall i publish my code somewhere?
Cecil
If you want to share you code (could be nice!!) you can publish it in tips & tricks here in the forum and send it to Paul's resuorce site.

http://www.reelmediaproductions.com/cgi ... ourcesSite

I am looking for a way to design button for my web page in PB and put some text to it.
ARGENTINA WORLD CHAMPION
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Post by cecilcheah »

Done it and done it.

Now can anyone help me to understand this VC++ to PB conversion. Please?

Cecil
traumatic
PureBasic Expert
PureBasic Expert
Posts: 1661
Joined: Sun Apr 27, 2003 4:41 pm
Location: Germany
Contact:

Post by traumatic »

Well, COPYDATASTRUCTURE is already declared

The #if !defined(WM_COPYDATA) && !defined(WIN32) are compiler directives,
so you could simply define #WM_COPYDATA, but again PureBasic already did that for you...

(... just to let you know: you'd write #WM_COPYDATA = $4a)

I didn't quite get what you're trying to do, but wouldn't a simple
SendMessage_( hWnd, #WM_COPYDATA, 0, @Data) be enough?
The whole function just returns #TRUE on success.

(of course "Data" can't be used - it's reserved by PB)



I'm in a hurry right now - hope that helped a bit though.
Good programmers don't comment their code. It was hard to write, should be hard to read.
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »

My attempt:

Code: Select all

BOOL TB_execute( HWND hWnd, BOOL bSysSuspendOff, LPCSTR lpStatements )
To:

Code: Select all

Procedure TB_execute(hWnd, bSysSuspendOff, lpStatements.s)
You don't need this:

Code: Select all

#if !defined(WM_COPYDATA) && !defined(WIN32) 

                              #define WM_COPYDATA   0x4a // as for WIN32 

                              typedef struct tagCOPYDATASTRUCT 
                              { 
                                 DWORD dwData;    // a place to put just 32 bits of data 
                                 DWORD cbData;   // size in bytes of data pointed to by PVOID 
                                 LPVOID lpData;   // other data to be passed to the reciving app 
                              } COPYDATASTRUCT, FAR * LPCOPYDATASTRUCT; 
                           #endif
I think the following was correctly translated, but I think it's weird (a one byte array to store a null terminated string?), but I'm not a C guru:

Code: Select all

       char       szStatements[1];       // A zero-terminated ASCII
                           string containing                                                         // the OpenScript
                           statements to be executed. 
El_Choni
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

El_Choni wrote:I think the following was correctly translated, but I think it's weird (a one byte array to store a null terminated string?), but I'm not a C guru:

Code: Select all

       char       szStatements[1];       // A zero-terminated ASCII
                           string containing                                                         // the OpenScript
                           statements to be executed. 
I guess it's possible that it uses the same trick I do where you have an array at the end of a structure and allocate some memory bigger than the structure. You then overwrite the end of the array on purpose, to be able to store as much data as you allocated memory for.

If that's the case, you need to make the "1" a "0" in PureBasic (zero length arrays in structures do not have bounds checking).
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Post by cecilcheah »

Hi there

Do you mean i do not have to translate this at all?

Code: Select all

BOOL TB_execute( HWND hWnd, BOOL bSysSuspendOff, LPCSTR lpStatements ) 
{ 
       BOOL                                   bResult; 
       LPCOPYDATA_EXECUTEDATA       lpExec; 
       COPYDATASTRUCT                     Data; 

       HANDLE  hStr; 

       Data.dwData = COPYDATA_EXECUTE; 
       Data.cbData = sizeof(*lpExec) + lstrlen(lpStatements) + 1; 

       hStr = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE, (DWORD)(Data.cbData)); 
       if (hStr != NULL) { 
              lpExec = (LPCOPYDATA_EXECUTEDATA)GlobalLock(hStr); 
              if ( lpExec != NULL ) 
              { 
                  Data.lpData = lpExec; 

                  lpExec->bSysSuspendOff = bSysSuspendOff; 
                  lstrcpy(lpExec->szStatements, lpStatements ); 

                  bResult = ( SendMessage(       hWnd, WM_COPYDATA, 
                                          NULL, (LPARAM)(LPVOID)&Data ) != 0 ); 
                  GlobalUnlock(hStr); 
              } else { 
                  bResult       = FALSE; 
              } 
              GlobalFree(hStr); 
       } else { 
              bResult       = FALSE; 
       } 

       return bResult; 
}
All i need to do is translate

Code: Select all

Code: 
BOOL TB_execute( HWND hWnd, BOOL bSysSuspendOff, LPCSTR lpStatements ) 
into this:

Code: Select all

Procedure TB_execute(hWnd, bSysSuspendOff, lpStatements.s)
All i want to do is to call this TB_execute prozedere inside PB to send some commands to TB (an external application) to execute the lpStatements inside the TB application.

Can someone please help me to make it work.

Cecil[/quote]
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »

No, no, this is what you don't need:

Code: Select all

#if !defined(WM_COPYDATA) && !defined(WIN32) 

                                                    #define WM_COPYDATA   0x4a // as for WIN32 

                                                    typedef struct tagCOPYDATASTRUCT 
                                                    { 
                                                       DWORD dwData;    // a place to put just 32
                      bits of data 
                                                       DWORD cbData;   // size in bytes of data
                      pointed to by PVOID 
                                                       LPVOID lpData;   // other data to be passed to
                      the reciving app 
                                                    } COPYDATASTRUCT, FAR * LPCOPYDATASTRUCT; 
                                                 #endif
Anyway, a more complete attempt:

Code: Select all

Structure COPYDATA_EXECUTE
  bSysSuspendOff.l
  szStatements.b[0]
EndStructure

#COPYDATA_EXECUTE = 3

Procedure TB_execute(hWnd, bSysSuspendOff, lpStatements.s)
  MyData.COPYDATASTRUCT
  MyData\dwData = #COPYDATA_EXECUTE
  MyData\cbData = SizeOf(COPYDATA_EXECUTE)+Len(lpStatements)+1
  hStr = GlobalAlloc_(#GMEM_ZEROINIT|#GMEM_MOVEABLE, MyData\cbData)
  If hStr
    *lpExec.COPYDATA_EXECUTE = GlobalLock_(hStr)
    If *lpExec
      MyData\lpData = *lpExec
      *lpExec\bSysSuspendOff = bSysSuspendOff
      CopyMemoryString(lpStatements, @*lpExec\szStatements)
      bResult = SendMessage_(hWnd, #WM_COPYDATA, #NULL, MyData)
      GlobalUnlock_(hStr)
    Else
      bResult = #FALSE
    EndIf
    GlobalFree_(hStr)
  Else
    bResult = #FALSE
  EndIf
  ProcedureReturn bResult
EndProcedure
BTW, what is this code used for?
El_Choni
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Syntax Error

Post by cecilcheah »

Hi

I am getting a syntax error on compiling the code here:

Code: Select all

CopyMemoryString(lpStatements, @*lpExec\szStatements)
I check the help file, it seems OK. Where is the error? Can you help more?

Cecil
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Post by cecilcheah »

Some more.

If i replace the statement with this:

Code: Select all

CopyMemoryString(lpStatements, @*lpExec\szStatements[0] )
I am getting a Windows General Protection Fault.

What shall i do?

Cecil
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »



I am getting a syntax error on compiling the code here:

Code:
CopyMemoryString(lpStatements, @*lpExec\szStatements)
This compiles ok here. Check the structure and procedure definitions:

Code: Select all

...
Structure COPYDATA_EXECUTE 
  bSysSuspendOff.l 
  szStatements.b[0]
EndStructure
...
Procedure TB_execute(hWnd, bSysSuspendOff, lpStatements.s)
...
*lpExec.COPYDATA_EXECUTE = GlobalLock_(hStr)
...
CopyMemoryString(lpStatements, @*lpExec\szStatements)
Maybe some other thing in your code?
El_Choni
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

CopyMemoryString(lpStatements, @*lpExec\szStatements)
From the example in the manual it looks like this needs to be a pointer to a pointer? e.g.

*foo = @*lpExec\szStatements
CopyMemoryString(lpStatements, @*foo)

But that looks a bit strange, so I do not know if I trust it ;)
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Post by cecilcheah »

Hi

If i use your code:

Code: Select all

*foo = @*lpExec\szStatements[0]
      CopyMemoryString(lpStatements, *foo) 
      MessageRequester("", "Hello",0)
It will give me a GPF.

And this:

Code: Select all

CopyMemoryString(lpStatements, @*lpExec\szStatements) 
will give me Syntax error. I think because szStatements is an array of [0]

Which manual did you find this ]*foo = @*lpExec\szStatements[0] ?
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Post by cecilcheah »

Wait, this is working:

Code: Select all

*foo = @*lpExec\szStatements[1]

      CopyMemoryString(lpStatements, @*foo) 
Thanks a lot for the help.

I am really learning a lot of this VC ++ stuff here, enforced.

Cecil
Post Reply