Releasing Variable used by WebService - web-services

How can I release a Variable that is being used by the WebService.
I'm using this form:
HttpPrincipal.WSDLLocation: = FrmPrincipal.edtWS.Text;
HttpPrincipal.Service: = 'CADServicesService';
HttpPrincipal.Port := 'CADServices';
Trinity: = HttpPrincipal as CADServices;
At the moment when I will close the Form appears an error, and discovered that when I declare this part:
Trinity: = HttpPrincipal as CADServices;
I think it is getting stuck in memory.
The error is the following:
"Invalid Pointer"
The error happens when you close the form, does not have any event in the OnClose or OnDestroy form.
Descriptions:
Trinity : CADServices,
HttpPrincipal is a THTTPRIO,
CADServices is my Unit containing all procedures / functions from WebService.

Instead of using the designtime component try to create HTTPRIO at runtime:
function GetCadServices(Addr : String): CadServices;
const
defSvc = 'CADServicesService';
defPrt = 'CADServices';
var
RIO: THTTPRIO;
begin
Result := nil;
RIO := THTTPRIO.Create(nil)
try
Result := (RIO as CadServices);
RIO.WSDLLocation := Addr;
RIO.Service := defSvc;
RIO.Port := defPrt;
finally
if (Result = nil) then
RIO.Free;
end;
end;
Usage:
Trinity := GetCadServices(FrmPrincipal.edtWS.Text);
If you imported the WSDL with the WSDL importer this code is automatically generated for you (look in the CadServices1 unit)

Related

Unit testing a HTTP handler that returns a stream of multiple files

HTTP handler
I have a HTTP handler like this:
func RouteHandler(c echo.Context) error {
outs := make([]io.Reader, 5)
for i := range outs {
outs[i] = // ... comes from a logic.
}
return c.Stream(http.StatusOK, "application/binary", io.MultiReader(outs...))
}
Unit test
I intend to write a unit test for HTTP handler and investigate the returned stream of multiple files.
I have these helper type and function for my unit test:
type Handler func(echo.Context) error
// Send request to a handler. Get back response body.
func Send(req *http.Request, handler Handler) ([]byte, error) {
w := httptest.NewRecorder()
e := echo.New()
c := e.NewContext(req, w)
// Call the handler.
err := handler(c)
if err != nil {
return nil, err
}
res := w.Result()
defer res.Body.Close()
return ioutil.ReadAll(res.Body)
}
Then, I use the above type and function to send a request to my HTTP handler from within my unit test:
// From within my unit test:
// Initialize request...
var data []byte
data, err := Send(request, RouteHandler)
// How to separate the multiple files returned here?
// How to work with the returned data?
Work with returned stream of files
How can I separate multiple files returned by the HTTP handler? How can I work with the stream of data returned by HTTP handler?
... Possible options: write a length followed by the content of a file...
Actually, the above option commented by #CeriseLimón was already implemented and was used by the front-end.

Use of Cocoa in C++ like in Delphi

There is a pattern in Delphi to work with Cocoa classes. A blog about this pattern is here:
Using OS X APIs directly from Delphi
I wonder, how it works and whether it can be done with xcode in C++ too.
As example I take the function "InternalGetMACOSPath" from System.IOUtils.pas. I put excerpts of the involved code at the end of this post. The line of code that I am interested in is:
nsFile := TNSFileManager.Wrap(TNSFileManager.OCClass.defaultManager);
In essence the following would be an equivalent in C++:
NSFileManagerClass* pFManagerClass;
NSFileManager* pFManager;
// GetOCClass
void* cls = objc_getClass("NSFileManager");
pFManagerClass = Import(cls);
// Wrap
pFManager = Import(pFManagerClass->defaultManager());
I like to know whether the dummy function "Import" can be defined by use of Objective-C Runtime functions. I guess that Delphi has to use the Objective-C Runtime functions in the end too. From where else could it have the informations for the vtables?
Code snippets:
NSFileManager = interface(NSObject)
['{9736DF94-95E9-4111-8C94-82D5EFF52A81}']
function URLForDirectory(directory: NSSearchPathDirectory; inDomain: NSSearchPathDomainMask; appropriateForURL: NSURL; create: Boolean; error: PPointer): NSURL; cdecl;
...
NSFileManagerClass = interface(NSObjectClass)
['{E666ADEB-9DBE-4BF0-BEE0-5912CF9F5AB4}']
{class} function defaultManager: Pointer; cdecl;
end;
TOCImport = class(TRawVirtualClass, ILocalObject)
TOCGenericImport<C: IObjectiveCClass; T: IObjectiveCInstance> = class(TOCImport)
TNSFileManager = class(TOCGenericImport<NSFileManagerClass, NSFileManager>) end;
class function TOCGenericImport<C,T>.GetOCClass: C;
var
ClassImport: TOCImport;
ClsID: Pointer;
ITypeInfo: PTypeInfo;
CTypeInfo: PTypeInfo;
begin
ITypeInfo := TypeInfo(T);
CTypeInfo := TypeInfo(C);
ClsID := objc_getClass(MarshaledAString(ShortStrToUTF8String(#ITypeInfo^.Name)));
FClassVTable := TOCVTable.Create(CTypeInfo, False);
ClassImport := TOCImport.Create(ClsId, nil, FClassVTable);
ClassImport.QueryInterface(GetTypeData(CTypeInfo)^.Guid, FOCClass);
Result := FOCCLass;
end;
class function TOCGenericImport<C,T>.Wrap(P: Pointer): T;
var
ObjID: Pointer;
Obj: TOCImport;
ITypeInfo: PTypeInfo;
begin
ITypeInfo := TypeInfo(T);
Obj := TOCImport.Create(P, nil, GetInstanceVTable);
Obj.QueryInterface(GetTypeData(ITypeInfo)^.Guid, Result);
end;
class function TPath.InternalGetMACOSPath(const SearchedPath: NSSearchPathDirectory; const SearchMask: NSSearchPathDomainMask): string;
var
nsFile: NSFileManager;
URL: NSURL;
begin
nsFile := TNSFileManager.Wrap(TNSFileManager.OCClass.defaultManager);
URL := nsFile.URLForDirectory(SearchedPath, SearchMask, nil, true, nil);

GetSaveFileName fails with CDERR_FINDRESFAILURE

I've written a TOpenPictDialog (source code see below) component, which finally fails under certain circumstands when calling
Result := TDialogFunc(DialogFunc)(DialogData);
in Dialogs.pas. As DialogFunc correctly points to GetOpenFileName I call CommDlgExtendedError afterwards for test to find out what's wrong. It returns CDERR_FINDRESFAILURE. In this case the dialog is simply not showing. My test form only contains a button and the TOpenPictDialog component, when pressing the button, OpenPictDialog1->Execute is called - that's all.
The very strange thing is that it does work perfectly (besides of the TListView flickering on resize) under one of the following circumstands:
a) add ExtDlgs in "uses" in calling form
b) add an original TOpenPictureDialog to the form without calling it
c) adding the PAS file containing TOpenPictDialog to the project (although TOpenPictDialog has been already installed)
If I write a C++ Builder application with the one calling form I never get TOpenPictDialog working (even if I add the additional TOpenPictureDialog component).
unit PictureDlg;
{$R-,H+,X+}
{$IF CompilerVersion > 23} {$DEFINE GE_DXE2} {$IFEND}
interface
{$IFDEF GE_DXE2}
uses Winapi.Messages, Winapi.Windows, System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls,
Vcl.Graphics, Vcl.ExtCtrls, Vcl.Buttons, Vcl.Dialogs, Vcl.ExtDlgs, Vcl.Consts, Vcl.ComCtrls;
{$ELSE}
uses Messages, Windows, SysUtils, Classes, Controls, StdCtrls,
Graphics, ExtCtrls, Buttons, Dialogs, ExtDlgs, Consts, ComCtrls;
{$ENDIF}
(*$HPPEMIT '// Alias records for C++ code that cannot compile in STRICT mode yet.' *)
(*$HPPEMIT '#if defined(_VCL_ALIAS_RECORDS)' *)
(*$HPPEMIT '#if !defined(STRICT)' *)
// (*$HPPEMIT ' #pragma alias "#Vcl#Extdlgs#TOpenPictDialog#Execute$qqrpv"="#Vcl#Extdlgs#TOpenPictDialog#Execute$qqrp6HWND__"' *)
(*$HPPEMIT '#endif' *)
(*$HPPEMIT '#endif' *)
type
{ TOpenPictDialog }
TOpenPictDialog = class(TOpenDialog)
private
FListView: TListView;
FTopLabel, FBottomLabel: TStaticText;
FImageCtrl: TImage;
FSavedFilename: string;
FOldDialogWndProc: Pointer;
FDialogMethodInstance: Pointer;
FDialogHandle: THandle;
function IsFilterStored: Boolean;
procedure DialogWndProc(var Msg: TMessage);
protected
procedure DoClose; override;
procedure DoSelectionChange; override;
procedure DoShow; override;
function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool; override;
published
property Filter stored IsFilterStored;
public
constructor Create(AOwner: TComponent); override;
function Execute(ParentWnd: HWND): Boolean; override;
property DialogListView: TListView read FListView;
property DialogImage: TImage read FImageCtrl;
property TopLabel: TStaticText read FTopLabel;
property BottomLabel: TStaticText read FBottomLabel;
end;
procedure Register;
implementation
uses
{$IFDEF GE_DXE2}
{$IF DEFINED(CLR)}
System.Runtime.InteropServices, System.Reflection, System.Security.Permissions, System.IO,
{$IFEND}
System.Math, Vcl.Forms, Winapi.CommDlg, Winapi.Dlgs, System.Types, Winapi.ShlObj, Winapi.ActiveX;
{$ELSE}
{$IF DEFINED(CLR)}
InteropServices, Reflection, Permissions, IO,
{$IFEND}
Math, Forms, CommDlg, Dlgs, Types, ShlObj, ActiveX;
{$ENDIF}
{ TOpenPictDialog }
constructor TOpenPictDialog.Create(AOwner: TComponent);
begin
FDialogHandle := 0;
FDialogMethodInstance := NIL;
inherited Create(AOwner);
Filter := GraphicFilter(TGraphic);
FListView := TListView.Create(Self);
FImageCtrl := TImage.Create(Self);
with FListView do
begin
Name := 'ListView';
SetBounds(204, 5, 169, 200);
BevelOuter := bvNone;
BorderWidth := 6;
TabOrder := 1;
Color := clWindow;
ParentDoubleBuffered := false;
DoubleBuffered := true;
OwnerDraw := true;
Ctl3D := true;
with FImageCtrl do
begin
Picture := nil;
Name := 'Image';
Parent := FListView;
end;
end;
FTopLabel := TStaticText.Create(Self);
with FTopLabel do
begin
Name := 'TopLabel';
SetBounds(6, 6, 157, 23);
AutoSize := False;
Caption := 'Preview:';
end;
FBottomLabel := TStaticText.Create(Self);
with FBottomLabel do
begin
Name := 'BottomLabel';
SetBounds(6, 6, 157, 23);
AutoSize := False;
Caption := 'Image size: 208 x 149 px';
Alignment := taCenter;
end;
end;
procedure TOpenPictDialog.DialogWndProc(var Msg: TMessage);
var
PreviewRect, ListViewRect, WindowRect, LabelRect: TRect;
WndControl: HWND;
begin
Msg.Result := CallWindowProc(FOldDialogWndProc, FDialogHandle, Msg.Msg, Msg.WParam, Msg.LParam);
if ((Msg.Msg = WM_WINDOWPOSCHANGED) and
((TWMWindowPosMsg(Msg).WindowPos.Flags and SWP_NOSIZE) = 0)) or
(Msg.Msg = WM_SHOWWINDOW) then begin
PreviewRect := FListView.BoundsRect;
GetWindowRect(Handle, WindowRect);
WndControl := FindWindowEx(FDialogHandle, 0, 'SHELLDLL_DefView', nil);
WndControl := FindWindowEx(WndControl, 0, 'SysListView32', nil);
if WndControl <> 0 then begin
GetWindowRect(WndControl, ListViewRect);
PreviewRect.Top := ListViewRect.Top - WindowRect.Top;
PreviewRect.Bottom := PreviewRect.Top + ListViewRect.Bottom - ListViewRect.Top;
if (not EqualRect(PreviewRect, FListView.BoundsRect)) then
FListView.BoundsRect := PreviewRect;
LabelRect := PreviewRect;
Dec(LabelRect.Top, 24);
LabelRect.Bottom := LabelRect.Top + 16;
FTopLabel.BoundsRect := LabelRect;
LabelRect := PreviewRect;
LabelRect.Top := PreviewRect.Bottom + 9;
LabelRect.Bottom := LabelRect.Top + 16;
FBottomLabel.BoundsRect := LabelRect;
end;
end;
end;
procedure TOpenPictDialog.DoSelectionChange;
var
FullName: string;
function ValidFile(const FileName: string): Boolean;
begin
Result := FileGetAttr(FileName) <> -1;
end;
begin
FullName := FileName;
if FullName <> FSavedFilename then
begin
FSavedFilename := FullName;
end;
inherited DoSelectionChange;
end;
procedure TOpenPictDialog.DoClose;
begin
if Assigned(FDialogMethodInstance) then begin
SetWindowLong(FDialogHandle, GWL_WNDPROC, Integer(FOldDialogWndProc));
FreeObjectInstance(FDialogMethodInstance);
end;
FDialogHandle := 0;
FDialogMethodInstance := NIL;
inherited DoClose;
{ Hide any hint windows left behind }
Application.HideHint;
end;
procedure TOpenPictDialog.DoShow;
var
PreviewRect, StaticRect, OldDialogRect: TRect;
DialogWidth, DialogHeight, NewLeft, NewTop: integer;
const
SizeIncrease = 25;
begin
FDialogHandle := GetParent(Handle);
GetWindowRect(FDialogHandle, OldDialogRect);
DialogWidth := OldDialogRect.Right - OldDialogRect.Left + SizeIncrease;
DialogHeight := OldDialogRect.Bottom - OldDialogRect.Top;
NewLeft := (Screen.Width - DialogWidth) div 2;
NewTop := (Screen.Height - DialogHeight) div 2;
GetWindowRect(Handle, PreviewRect);
MoveWindow(FDialogHandle, NewLeft, NewTop, DialogWidth, DialogHeight, true);
MoveWindow(Handle, 0, 0, PreviewRect.Right - PreviewRect.Left + SizeIncrease, PreviewRect.Bottom - PreviewRect.Top, false);
StaticRect := GetStaticRect;
GetClientRect(Handle, PreviewRect);
PreviewRect.Left := StaticRect.Left + (StaticRect.Right - StaticRect.Left);
Inc(PreviewRect.Top, 4);
Dec(PreviewRect.Right, 8);
Dec(PreviewRect.Bottom, 20);
FListView.BoundsRect := PreviewRect;
FDialogMethodInstance := MakeObjectInstance(DialogWndProc);
FOldDialogWndProc := Pointer(SetWindowLong(FDialogHandle, GWL_WNDPROC, Integer(FDialogMethodInstance)));
FSavedFilename := '';
FListView.ParentWindow := Handle;
FTopLabel.ParentWindow := Handle;
FBottomLabel.ParentWindow := Handle;
inherited DoShow;
end;
[UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.SafeSubWindows)]
function TOpenPictDialog.Execute(ParentWnd: HWND): Boolean;
begin
if NewStyleControls and not (ofOldStyleDialog in Options) and not
((Win32MajorVersion >= 6) and UseLatestCommonDialogs) then
Template := 'DLGTEMPLATE'
else
{$IF DEFINED(CLR)}
Template := '';
{$ELSE}
Template := nil;
{$IFEND}
Result := inherited Execute(ParentWnd);
end;
function TOpenPictDialog.TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
begin
// This makes sense ONLY if you are compiling with a run-time packages
// Thanks to Peter Below (www.delphifaq.com)
TOpenfilename(Dialogdata).hInstance := FindClassHInstance(Classtype);
Result := inherited TaskModalDialog(DialogFunc, DialogData);
end;
function TOpenPictDialog.IsFilterStored: Boolean;
begin
Result := not (Filter = GraphicFilter(TGraphic));
end;
procedure Register;
begin
RegisterComponents('Dialogs', [TOpenPictDialog]);
end;
end.
When you copied the code from ExtDlgs.pas to begin writing yours, you didn't copy enough. In particular, you didn't copy the $R directive that links the associated ExtDlgs.rc file, which contains the dialog resource describing the additional layout of the custom dialog box.
Your code tells the API to use a dialog resource named DLGTEMPLATE, but you haven't included that resource in your program. That explains why the error code you get is about a failure to find a resource. Using the ExtDlgs unit has the side effect of linking that unit's associated resources.
Go copy the dialog template from ExtDlgs.rc into your own RC file and link it as ExtDlgs.pas does. Use a different name for the resource, though, to avoid a name clash with the existing DLGTEMPLATE resource. Adjust your code accordingly.

Delphi COM Passing ByteArray as OleVariant

I'm interfacing fingerprint reader via COM and i need help converting VB.NET and C++ Code to Delphi.
The API takes olevariant as parameter:
Function FingerPrint.GetData(var ImageData : OleVariant) : WordBool;
VB.NET example provided:
Dim imgData() as Byte
ReDim imgData(fingerPrint.ImageSize) as Byte
If fingerPrint.GetData(imgData) = True Then
'Success
End If
C++ example provided:
BYTE* dataBuff = new BYTE[fingerPrint.ImageSize];
VARIANT imgData;
imgData.vt = VT_BYREF|VT_UI1;
imgData.pbVal = dataBuff;
if(fingerPrint.getData(imgData) == TRUE) {
//Success
}
Here's my Delphi Code:
procedure GetImgData();
var varBuffer : OleVariant;
imgBuff : PByteArray;
begin
GetMem(imgBuff, fingerPrint.ImageSize);
try
tagVariant(varBuffer).vt := VT_UI1 or VT_BYREF; // 0x4011
tagVariant(varBuffer).pbVal := Pointer(imgBuff);
if fingerPrint.getData(varBuffer) then
begin
// success
end;
finally
FreeMem(imgBuff);
end;
end;
another approach:
procedure GetImgData();
var varBuffer : OleVariant;
tagV : TVariantArg;
imgBuff : PByteArray;
begin
GetMem(imgBuff, fingerPrint.ImageSize);
try
tagV.vt := VT_UI1 or VT_BYREF; // 0x4011
tagV.pbVal := Pointer(imgBuff);
varBuffer := OleVariant(tagV);
if fingerPrint.getData(varBuffer) then
begin
// success
end;
finally
FreeMem(imgBuff);
end;
end;
getData is not returning true using the parameter i'm sending. Sent my executable to support and told me that API is getting 0x400C (VT_VARIANT or VT_BYREF) instead of 0x4011.
Anything wrong with my Code?
Please Help!
UPDATE:
here's from dispinterface
function GetData(var ImageData: OleVariant): WordBool; dispid 23;
from Component Wrapper
..
function GetData(var ImageData : OleVariant): WordBool;
..
function TFingerPrint.GetData(var ImageData : OleVariant): WordBool;
begin
Result := DefaultInterface.GetData(ImageData);
end;
C++ declaration
BOOL getData(const VARIANT FAR& imgData)
UPDATE 20140313
Our supplier sent new OCX to handle data received from Delphi.
Are you sure it's 0x4011 and not 0x2011? Since varArray = $2000 and VarArrayCreate([0,size-1],varByte) would create an OleVariant with an array of varByte's like the VB code. If that works, use VarArrayLock and VarArrayUnlock to access the data.

Inno Setup/Pascal Scripting - Casting Returning Nil

I'm trying to write some Pascal script for a installer I'm making with Inno Setup Compiler 5.5.1. I'm currently trying to add a custom wizard page that executes a command, taking user input from text fields (TEdit components). I defined the NextButtonClick function, and it checks that the Page ID is the custom page I defined and attempts to retrieve the user input from the field. When I get it from the components of the Page's Surface property, it gets returned as a TComponent. To get the next I need to cast it to a TEdit, so I tried casting it and it seems to be returning nil. Besides the scripting for Inno I've been doing for the past few days, I don't have much experience with Pascal, so I could possibly be doing something wrong. But I'd appreciate the help!
Here's the chunk of code giving me an issue for reference (with debugging lines left in):
function NextButtonClick(CurPageID: Integer): Boolean;
var
ResultCode: Integer;
CurrPage: TWizardPage;
Server : TComponent;
Server2: TEdit;
SurfacePage : TNewNotebookPage;
ServerStr : String;
begin
if CurPageID = 100 then
begin
CurrPage := PageFromID(100);
SurfacePage := CurrPage.Surface;
Server := SurfacePage.Controls[0];
Server2 := TEdit(Server); // RETURNS NIL HERE
if Server2 = nil then
MsgBox('', mbInformation, MB_OK);
ServerStr := Server2.Text;
MsgBox(ServerStr, mbInformation, MB_OK);
//ShellExec('', 'sqlcmd', '-S ' + ServerStr + ' -Q ":r setMemUsage.sql"', ExpandConstant('{app}') + '\sql', SW_SHOW, ewWaitUntilTerminated, ResultCode);
end;
Result := True;
end;
I can't simulate your problem. I've used this minimalistic code:
[Code]
var
CustomPageID: Integer;
procedure InitializeWizard;
var
EditBox: TEdit;
CustomPage: TWizardPage;
begin
CustomPage := CreateCustomPage(wpWelcome, '', '');
CustomPageID := CustomPage.ID;
EditBox := TEdit.Create(WizardForm);
EditBox.Parent := CustomPage.Surface;
end;
procedure CurPageChanged(CurPageID: Integer);
var
EditBox: TEdit;
Component: TComponent;
CustomPage: TWizardPage;
begin
if (CurPageID = CustomPageID) then
begin
CustomPage := PageFromID(CustomPageID);
Component := CustomPage.Surface.Controls[0];
if (Component is TEdit) then
begin
MsgBox('Controls[0] is assigned and is TEdit', mbInformation, MB_OK);
EditBox := TEdit(Component);
EditBox.Text := 'Hi, I''m just a modified edit text!';
end;
end;
end;