Convert to Purebasic

Für allgemeine Fragen zur Programmierung mit PureBasic.
Wayne-C
Beiträge: 12
Registriert: 13.11.2015 14:59

Convert to Purebasic

Beitrag von Wayne-C »

Hello PureBasic community,

In order to print the contents of a WebGadget with custom Header and Footer, I would like to have the following Code converted to PureBasic. As this is more a coding Job then a question, I would pay €50 (Paypal, Paymit in CH) for a working solution in pure PB :-)

The printing will be started from this code:

Code: Alles auswählen

WebGadget(#WebGadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window), ServerURL)
WebBrowser.IWebBrowser2 = GetWindowLong_(GadgetID(#WebGadget), #GWL_USERDATA)
WebBrowser\ExecWB(#OLECMDID_PRINT, #OLECMDEXECOPT_PROMPTUSER, 0, 0)
The Code I have found which is to be converted:
https://support.microsoft.com/de-ch/kb/267240

Code: Alles auswählen

LRESULT CWebOCWindow::OnPrint(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) {
	SAFEARRAYBOUND psabBounds[1];
	SAFEARRAY *psaHeadFoot;
	HRESULT hr = S_OK;

	// Variables needed to send IStream header to print operation.
	HGLOBAL hG = 0;
	IStream *pStream= NULL;
	IUnknown *pUnk = NULL;
	ULONG lWrote = 0;
	LPSTR sMem = NULL;
	
	if (!webOC) {
		ATLTRACE(_T("DoPrint: Cannot print - WebBrowser control not ready\n"));
		goto cleanup;
	}
	
	// Initialize header and footer parameters to send to ExecWB().
	psabBounds[0].lLbound = 0;
	psabBounds[0].cElements = 3;
	psaHeadFoot = SafeArrayCreate(VT_VARIANT, 1, psabBounds);
	if (NULL == psaHeadFoot) {
		// Error handling goes here.
		goto cleanup;
	}
	VARIANT vHeadStr, vFootStr, vHeadTxtStream;
	long rgIndices;
	VariantInit(&vHeadStr);
	VariantInit(&vFootStr);
	VariantInit(&vHeadTxtStream);

	// Argument 1: Header
	vHeadStr.vt = VT_BSTR;
	vHeadStr.bstrVal = SysAllocString(L"This is my header string.");
	if (vHeadStr.bstrVal == NULL) {
		goto cleanup;
	}
	
	// Argument 2: Footer
	vFootStr.vt = VT_BSTR;
	vFootStr.bstrVal = SysAllocString(L"This is my footer string.");
	if (vFootStr.bstrVal == NULL) {
		ATLTRACE(_T("DoPrint: Could not allocate memory in %s: Line %d\n"), __FILE__, __LINE__);
		goto cleanup;
	}

	// Argument 3: IStream containing header text. Outlook and Outlook 
         // Express use this to print out the mail header. 	
	if ((sMem = (LPSTR)CoTaskMemAlloc(512)) == NULL) {
		ATLTRACE(_T("DoPrint: Could not allocate memory in %s: Line %d\n"), __FILE__, __LINE__);
		goto cleanup;
	}
	// We must pass in a full HTML file here, otherwise this 
         // becomes corrupted when we print.
	sprintf(sMem, "<html><body><strong>Printed By:</strong> Custom WebBrowser Host 1.0<p></body></html>\0");

	// Allocate an IStream for the LPSTR that we just created.
	hG = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, strlen(sMem));
	if (hG == NULL) {
		ATLTRACE(_T("DoPrint: Could not allocate memory in %s: Line %d\n"), __FILE__, __LINE__);
		goto cleanup;
	}
	hr = CreateStreamOnHGlobal(hG, TRUE, &pStream);
	if (FAILED(hr)) {
		ATLTRACE(_T("OnPrint::Failed to create stream from HGlobal: %lX\n"), hr);
		goto cleanup;
	}
	hr = pStream->Write(sMem, strlen(sMem), &lWrote);
	if (SUCCEEDED(hr)) {
	    // Set the stream back to its starting position.
		LARGE_INTEGER pos;
		pos.QuadPart = 0;
		pStream->Seek((LARGE_INTEGER)pos, STREAM_SEEK_SET, NULL);
		hr = pStream->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(&pUnk));
		vHeadTxtStream.vt = VT_UNKNOWN;
		vHeadTxtStream.punkVal = pUnk;
	}

	rgIndices = 0;
	SafeArrayPutElement(psaHeadFoot, &rgIndices, static_cast<void *>(&vHeadStr));
	rgIndices = 1;
	SafeArrayPutElement(psaHeadFoot, &rgIndices, static_cast<void *>(&vFootStr));
	rgIndices = 2;
	SafeArrayPutElement(psaHeadFoot, &rgIndices, static_cast<void *>(&vHeadTxtStream));
		
	//NOTE: Currently, the SAFEARRAY variant must be passed by using
	        // the VT_BYREF vartype when you call the ExecWeb method.
	VARIANT vArg;
	VariantInit(&vArg);
	vArg.vt = VT_ARRAY | VT_BYREF;
	vArg.parray = psaHeadFoot;
	hr = webOC->ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, &vArg, NULL);
	if (FAILED(hr)) {
		ATLTRACE(_T("DoPrint: Call to WebBrowser's ExecWB failed: %lX\n"), hr);
	goto cleanup;
	}
	return 1; 
	//WebBrowser control will clean up the SAFEARRAY after printing.
	cleanup:
	VariantClear(&vHeadStr);
	VariantClear(&vFootStr);
	VariantClear(&vHeadTxtStream);
	if (psaHeadFoot) {
		SafeArrayDestroy(psaHeadFoot);
	}
	if (sMem) {
		CoTaskMemFree(sMem);	
	}
	if (hG != NULL) {
		GlobalFree(hG);
	}
	if (pStream != NULL) {
		pStream->Release();
		pStream = NULL;
	}
	bHandled = TRUE;
	return 0;
}
Thank you in advance,
Kind regards
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Convert to Purebasic

Beitrag von edel »

Code: Alles auswählen

#OLECMDID_PRINT = 6
#OLECMDEXECOPT_PROMPTUSER = 1
#OLECMDEXECOPT_DONTPROMPTUSER = 2

Procedure OnPrint()
  Protected WebBrowser.IWebBrowser2 = GetWindowLongPtr_(GadgetID(0), #GWLP_USERDATA)
  Protected Dim psabBounds.safearraybound(0)
  Protected *psaHeadFoot.safearray
  Protected.VARIANT vHeadStr, vFootStr, vHeadTxtStream, vArg
  Protected sMem.s = "<html><body><strong>Printed By:</strong> Custom WebBrowser Host 1.0<p></body></html>"
  Protected hg.i, hr.i, lWrote.l
  Protected rgIndices.l
  Protected *pStream.IStream 
  Protected *pUnk.IUnknown
  
  psabBounds(0)\lLbound = 0
  psabBounds(0)\cElements = 3
  
  *psaHeadFoot = SafeArrayCreate_(#VT_VARIANT, 1, @psabBounds())
  VariantInit_(@vHeadStr)
  VariantInit_(@vFootStr)
  VariantInit_(@vHeadTxtStream)
  
  vHeadStr\vt = #VT_BSTR
  vHeadStr\bstrVal = SysAllocString_("This is my header string.")
  
  vFootStr\vt = #VT_BSTR
  vFootStr\bstrVal = SysAllocString_("This is my footer string.")  
  
  If (vHeadStr\bstrVal = #Null) 
    ; cleanup
  EndIf
    
  If (vFootStr\bstrVal = #Null) 
    Goto cleanup
  EndIf
  
  hG = GlobalAlloc_(#GMEM_FIXED | #GMEM_ZEROINIT, Len(sMem))
  If Not hg 
    Goto cleanup
  EndIf
  
  hr = CreateStreamOnHGlobal_(hG, #True, @*pStream)
  If Not hr = 0
    Goto cleanup
  EndIf 
  
  hr = *pStream\Write(@sMem, StringByteLength(sMem), @lWrote)
  If hr = 0
    
      Protected pos.LARGE_INTEGER
      *pStream\Seek(pos, #STREAM_SEEK_SET, #Null)
      hr = *pStream\QueryInterface(?IID_IUnknown, @*pUnk)
      vHeadTxtStream\vt = #VT_UNKNOWN;
      vHeadTxtStream\punkVal = *pUnk
    
  EndIf 
  
  rgIndices = 0;
  SafeArrayPutElement_(*psaHeadFoot, @rgIndices, @vHeadStr)
  rgIndices = 1                                            
  SafeArrayPutElement_(*psaHeadFoot, @rgIndices, @vFootStr)
  rgIndices = 2                                            
  SafeArrayPutElement_(*psaHeadFoot, @rgIndices, @vHeadTxtStream)
  
  VariantInit_(@vArg)
  vArg\vt = #VT_ARRAY | #VT_BYREF
  vArg\parray = *psaHeadFoot
  hr = WebBrowser\ExecWB(#OLECMDID_PRINT, #OLECMDEXECOPT_PROMPTUSER, @vArg, #Null)
  ;hr = WebBrowser\ExecWB(#OLECMDID_PRINT, #OLECMDEXECOPT_DONTPROMPTUSER, @vArg, #Null)
  If Not hr = 0
    Goto cleanup
  EndIf
  
  ProcedureReturn 1
  
  cleanup:
   VariantClear_(@vHeadStr)
   VariantClear_(@vFootStr)
   VariantClear_(@vHeadTxtStream)
   If (*psaHeadFoot) 
      SafeArrayDestroy_(*psaHeadFoot)
   EndIf
   
   If (hG <> #Null) 
      GlobalFree_(hG)
    EndIf
    
   If (*pStream <> #Null) 
      *pStream\Release()
   EndIf
   
   ProcedureReturn 0
  
EndProcedure


If OpenWindow(0, 0, 0, 1024, 768, "")
  
  CreateMenu(0, WindowID(0))
  MenuTitle("Project")
  MenuItem(1, "Print"   +Chr(9)+"Ctrl+P")

  
  WebGadget(0, 0, 0, WindowWidth(0), WindowHeight(0) - MenuHeight(), "google.de")
  BindMenuEvent(0, 1, @OnPrint())
  
  Repeat    
  Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf


DataSection
  IID_IUnknown:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection

Wayne-C
Beiträge: 12
Registriert: 13.11.2015 14:59

Re: Convert to Purebasic

Beitrag von Wayne-C »

@edel: It works! Thank you very much! See my PN :-)

BTW this solution should probably go to the CodeArchiv?

Kind regards,
Wayne-C
Beiträge: 12
Registriert: 13.11.2015 14:59

Re: Convert to Purebasic

Beitrag von Wayne-C »

I cleaned up a bit :-)

Code: Alles auswählen

; Unicode Executable!

#OLECMDID_PRINT = 6
#OLECMDID_PRINTPREVIEW = 7
#OLECMDID_PAGESETUP = 8
#OLECMDEXECOPT_PROMPTUSER = 1
#OLECMDEXECOPT_DONTPROMPTUSER = 2

Header$ = "HEAD-LEFT&bHEAD-CENTER&bHEAD-RIGHT"
Footer$ = "FOOT-LEFT&bFOOT-CENTER&bFOOT-RIGHT"

; Header$ = "&w&b&b&u"
; Footer$ = "&d at &t&b"+UserName()+"&bPage &p/&P"

If OpenWindow(0, 0, 0, 600, 500, "Webgadget Print", #PB_Window_SystemMenu)
	AddKeyboardShortcut(0, #PB_Shortcut_Control|#PB_Shortcut_P, 101)
	
	WebGadget(0, 0, 0, 600, 500, "http://www.google.com/")
	WebBrowser.IWebBrowser2 = GetWindowLong_(GadgetID(0), #GWL_USERDATA)
	
	Repeat
		WEvent = WindowEvent()
		If WEvent
			If WEvent = #PB_Event_CloseWindow
				Break
			ElseIf WEvent = #PB_Event_Menu
				EventMenu.l = EventMenu()
				If EventMenu = 101
					vHeadStr.VARIANT\vt = #VT_BSTR
					vHeadStr\bstrVal = SysAllocString_(Header$)
					vFootStr.VARIANT\vt = #VT_BSTR
					vFootStr\bstrVal = SysAllocString_(Footer$)
					
					psabBounds.SAFEARRAYBOUND\lLbound = 0
					psabBounds\cElements = 2
					
					*psaHeadFoot.SAFEARRAY = SafeArrayCreate_(#VT_VARIANT, 1, @psabBounds)
					rgIndices.l = 0
					SafeArrayPutElement_(*psaHeadFoot, @rgIndices, @vHeadStr)
					rgIndices= 1
					SafeArrayPutElement_(*psaHeadFoot, @rgIndices, @vFootStr)

					vArg.VARIANT\vt = #VT_ARRAY | #VT_BYREF
					vArg\parray = *psaHeadFoot
					WebBrowser\ExecWB(#OLECMDID_PRINT, #OLECMDEXECOPT_PROMPTUSER, @vArg, #Null)
					
					SysFreeString_(vHeadStr\bstrVal)
					SysFreeString_(vFootStr\bstrVal)
					SafeArrayDestroy_(*psaHeadFoot)
				EndIf
			EndIf
		Else
			Delay(10)
		EndIf
	ForEver
EndIf
End
Wayne-C
Beiträge: 12
Registriert: 13.11.2015 14:59

Re: Convert to Purebasic

Beitrag von Wayne-C »

FYI

Code: Alles auswählen

•&& = ampersand
•&b = right-justify
•&b&b = Text following the first "&b" in center alignment; text following the second "&b" in right-justified alignment
•&d = date (user short format)
•&D = date (user long format)
•&t = time (user preference)
•&T = time (military format)
•&p = page
•&P = number of pages
•&u = URL (or file path)
•&w = (window) title tag
Antworten