Find Emails in string with PerlRegex in Delphi - regex

I'm using regular expressions in Delphi with PerlRegex component, I have a regular expression perl perl works perfect, but when used in Delphi with PerlRegex component finds nothing
Code:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, PerlRegex;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
code: string;
regex: TPerlRegEx;
begin
code := 'sdaasd saassd test#hotmail.com sdasdsd test2#gmail.com sdsadsd asdasdasd';
regex := TPerlRegEx.Create();
regex.regex := 'qr/[A-Z0-9._%+-]+\#[A-Z0-9.-]+\.[A-Z]{2,4}/i';
regex.Subject := code;
while regex.MatchAgain do
begin
ShowMessage(regex.Groups[1]);
end;
end;
end.
As I can recover mails with PerlRegex?

qr/.../i is part of the Perl language, not just regex syntax. So this line
regex.regex := 'qr/[A-Z0-9._%+-]+\#[A-Z0-9.-]+\.[A-Z]{2,4}/i';
is wrong, and should be
regex.RegEx := '[A-Z0-9._%+-]+\#[A-Z0-9.-]+\.[A-Z]{2,4}';
regex.Options := [preCaseLess];

Related

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);

How to Mock Spring4D Events with DUnit

I am struggling to successfully mock a Spring4d Event with DUnit.
In fact I am more mocking a mock returning a mock of an event...
This is the basic structure.
TMyObject --EventContainer--> TMock<IEventContainer> --Event--> TMock<IEvent>
TMyObject has a property EventContainer : IEventContainer
IEventContainer has a property Event : IMyEvent
I want to mock
MyObject.EventContainer.Event.Add
I tested each possibility I could think of. I either get AVs or Invalid Casts. I've put the source code below. If anyone could help me to get this working that would be really nifty!
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
DUnitTestRunner,
Spring.Events,
Spring,
Classes,
TestFramework,
Delphi.Mocks;
//Unit1 in 'Unit1.pas';
type
{$M+}
IMyEvent = interface(IEvent<TNotifyEvent>)
procedure Add(const handler: TMethod);
end;
{$M-}
{$M+}
IMyEventMock = interface(IMyEvent)
procedure Add(const handler: TMethod);
end;
{$M-}
{$M+}
IEventContainer = interface(IInterface)
function GetEvent: IMyEvent;
procedure SetEvent(const Value: IMyEvent);
property Event: IMyEvent
read GetEvent
write SetEvent;
end;
{$M-}
{$M+}
ITestEventContainer = interface(IEventContainer)
function GetEvent: TMock<IMyEvent>;
procedure SetEvent(const Value: TMock<IMyEvent>);
property Event: TMock<IMyEvent>
read GetEvent
write SetEvent;
end;
{$M-}
{$REGION 'TEventContainer'}
TEventContainer = class(TInterfacedObject, IEventContainer)
private
FAEvent: IMyEvent;
function GetEvent: IMyEvent;
procedure SetEvent(const Value: IMyEvent);
public
property Event: IMyEvent
read GetEvent
write SetEvent;
end;
{$ENDREGION}
{$REGION 'TMyObject'}
TMyObject = class(TObject)
private
FEventContainer: IEventContainer;
function GetEventContainer: IEventContainer;
procedure SetEventContainer(const Value: IEventContainer);
public
property EventContainer: IEventContainer
read GetEventContainer
write SetEventContainer;
end;
{$ENDREGION}
{$REGION 'TMyObjectTest'}
TMyObjectTest = class(TTestCase)
strict private
FMyObject: TMyObject;
FMyEventContainerMock: TMock<IEventContainer>;
FMyTestEventContainerMock: TMock<ITestEventContainer>;
FEventMock: TMock<IMyEventMock>;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure Test_InstanceAsValue;
procedure Test_Value_Make;
procedure Test_Value_From;
procedure Test_Value_From_Instance;
procedure Test_Value_From_Variant;
procedure Test_Value_From_Variant_Instance;
procedure Test_Mocked_Container_Value_Make;
procedure Test_Mocked_Container_Value_From;
procedure Test_Mocked_Container_Value_From_Instance;
procedure Test_Mocked_Container_Value_From_Variant;
procedure Test_Mocked_Container_Value_From_Variant_Instance;
end;
{$ENDREGION}
{$REGION 'TEventContainer'}
function TEventContainer.GetEvent: IMyEvent;
begin
Result := FAEvent;
end;
procedure TEventContainer.SetEvent(const Value: IMyEvent);
begin
FAEvent := Value;
end;
{$ENDREGION}
{$REGION 'TMyObject'}
function TMyObject.GetEventContainer: IEventContainer;
begin
Result := FEventContainer;
end;
procedure TMyObject.SetEventContainer(const Value: IEventContainer);
begin
FEventContainer := Value;
end;
{$ENDREGION}
{$REGION 'TMyObjectTest'}
procedure TMyObjectTest.SetUp;
begin
inherited;
FMyObject := TMyObject.Create;
FMyEventContainerMock := TMock<IEventContainer>.Create;
FMyObject.EventContainer := FMyEventContainerMock;
end;
procedure TMyObjectTest.TearDown;
begin
inherited;
FMyObject.Free;
FMyObject := nil;
end;
procedure TMyObjectTest.Test_Value_Make;
var aValue : TValue;
begin
FEventMock := TMock<IMyEventMock>.Create;
TValue.Make(#FEventMock, TypeInfo(IMyEventMock), aValue);
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', aValue);
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_InstanceAsValue;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', FEventMock.InstanceAsValue);
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_From;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', FEventMock.InstanceAsValue);
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_From_Instance;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.From(FEventMock));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_From_Variant;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.FromVariant(FEventMock));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_From_Variant_Instance;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.FromVariant(FEventMock.Instance));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Mocked_Container_Value_Make;
var aValue : TValue;
begin
FMyTestEventContainerMock := TMock<ITestEventContainer>.Create;
FMyObject.EventContainer := FMyTestEventContainerMock;
FEventMock := TMock<IMyEventMock>.Create;
TValue.Make(#aValue, TypeInfo(TMock<IMyEventMock>), aValue);
FMyTestEventContainerMock.SetUp.WillReturnDefault('GetEvent', aValue);
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Value_From;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.From(FEventMock));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Value_From_Instance;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.From(FEventMock.Instance));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Value_From_Variant;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.FromVariant(FEventMock));
FMyObject.EventContainer.Event;
end;
procedure TMyObjectTest.Test_Value_From_Variant_Instance;
begin
FEventMock := TMock<IMyEventMock>.Create;
FMyEventContainerMock.SetUp.WillReturnDefault('GetEvent', TValue.FromVariant(FEventMock.Instance));
FMyObject.EventContainer.Event;
end;
begin
RegisterTest(TMyObjectTest.Suite);
try
DUnitTestRunner.RunRegisteredTests;
ReadLn;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
ReadLn;
end;
end;
end.
First your approach is wrong. Inheriting an interface and then adding {$M+} will only include method info for the methods added from there on. That means even if you add a method with the same signature as a parent interface has will not make the mock work because the code will still call the parent interfaces method and not the one you added.
Furthermore DelphiMocks in this case is the victim of a bug in TValue conversion of an interface to its parent type. This is just not supported - see Rtti.ConvIntf2Intf.
I would suggest compiling Spring4D with IEvent inheriting from IInvokable to get method info in there and avoid inheriting from it.
If you do that the following tests will pass - all others are just passing the mock wrong:
Test_InstanceAsValue;
Test_Value_From_Instance;
Test_Mocked_Container_Value_From;
In Spring4D 1.2 we are introducing a new interception library that is also used for our mocking solution. Also the container will be able to provide automocking. So you can write your test like this:
var
container: TContainer;
event: IMyEvent;
begin
container := TContainer.Create;
container.AddExtension<TAutoMockExtension>;
try
FMyObject.EventContainer := container.Resolve<ITestEventContainer>;
event := FMyObject.EventContainer.Event;
event.Add(nil);
finally
container.Free;
end;
end;
The container will create mocks for any type it needs to resolve that it does not know. In this test you could register the class you want to test and the container automatically injects any dependency as mock.
var
container: TContainer;
event: IMyEvent;
begin
container := TContainer.Create;
container.AddExtension<TAutoMockExtension>;
container.RegisterType<TMyObject>.InjectProperty('EventContainer');
container.Build;
try
FMyObject := container.Resolve<TMyObject>;
event := FMyObject.EventContainer.Event;
event.Add(nil);
finally
container.Free;
end;
end;
You can go even further and integrate the auto mocking container into a base testcase class:
program Project2;
{$APPTYPE CONSOLE}
uses
Classes,
SysUtils,
DUnitTestRunner,
TestFramework,
Spring.Events,
Spring,
Spring.Container,
Spring.Container.Registration,
Spring.Container.AutoMockExtension,
Spring.Mocking;
type
IMyEvent = IEvent<TNotifyEvent>;
IEventContainer = interface(IInvokable)
function GetEvent: IMyEvent;
procedure SetEvent(const Value: IMyEvent);
property Event: IMyEvent read GetEvent write SetEvent;
end;
TMyObject = class(TObject)
private
FEventContainer: IEventContainer;
public
property EventContainer: IEventContainer read FEventContainer write FEventContainer;
end;
TAutoMockingTestCase<T: class> = class(TTestCase)
protected
fContainer: TContainer;
fSUT: T;
procedure SetUp; overload; override;
procedure TearDown; override;
procedure SetUp(const registration: TRegistration<T>); reintroduce; overload; virtual;
end;
TMyTest = class(TAutoMockingTestCase<TMyObject>)
protected
procedure SetUp(const registration: TRegistration<TMyObject>); override;
published
procedure Test_EventAdd;
end;
procedure TAutoMockingTestCase<T>.SetUp(const registration: TRegistration<T>);
begin
end;
procedure TAutoMockingTestCase<T>.SetUp;
begin
inherited;
fContainer := TContainer.Create;
fContainer.AddExtension<TAutoMockExtension>;
SetUp(fContainer.RegisterType<T>);
fContainer.Build;
fSUT := fContainer.Resolve<T>;
end;
procedure TAutoMockingTestCase<T>.TearDown;
begin
fSUT.Free;
fContainer.Free;
inherited;
end;
procedure TMyTest.SetUp(const registration: TRegistration<TMyObject>);
begin
registration.InjectProperty('EventContainer');
end;
procedure TMyTest.Test_EventAdd;
begin
fSUT.EventContainer.Event.Add(nil);
end;
begin
RegisterTest(TMyTest.Suite);
try
DUnitTestRunner.RunRegisteredTests;
ReadLn;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
ReadLn;
end;
end;
end.

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.

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;

How can I query remembered UNC connections similar to "net use"?

I understand how to retrieve the UNC path for a mapped drive from the registry (HKEY_CURRENT_USER\Network), but I also have a need to retrieve remote connections to network resources that were not mapped.
For example, opening the 'Run' dialog and typing <\server0123\share$>. If I type "net use", I would see this mapping, but I have been unable to determine where on the file system or registry this information is stored.
alt text http://www.freeimagehosting.net/uploads/5bf1a0e3c5.jpg
Does anyone know have a location I can query this from, or an API I can call to obtain this? Suggestions involving vbscript, C, and Delphi are more than welcome!
Mick, try using the Win32_NetworkConnection WMI Class
check this sample
program GetWMI_Win32_NetworkConnection;
{$APPTYPE CONSOLE}
uses
SysUtils
,ActiveX
,ComObj
,Variants;
Procedure GetWin32_NetworkConnection;
var
objWMIService : OLEVariant;
colItems : OLEVariant;
colItem : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
function GetWMIObject(const objectName: String): IDispatch;
var
chEaten: Integer;
BindCtx: IBindCtx;
Moniker: IMoniker;
begin
OleCheck(CreateBindCtx(0, bindCtx));
OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));
OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
end;
begin
objWMIService := GetWMIObject('winmgmts:\\localhost\root\cimv2');
colItems := objWMIService.ExecQuery('SELECT * FROM Win32_NetworkConnection','WQL',0);
oEnum := IUnknown(colItems._NewEnum) as IEnumVariant;
while oEnum.Next(1, colItem, iValue) = 0 do
begin
Writeln('Caption '+colItem.Caption);
Writeln('Name '+colItem.Name);
Writeln('ConnectionState'+colItem.ConnectionState);
Writeln('ConnectionType '+colItem.ConnectionType);
Writeln('Description '+colItem.Description);
Writeln('DisplayType '+colItem.DisplayType);
Writeln('LocalName '+colItem.LocalName);
Writeln('ProviderName '+colItem.ProviderName);
Writeln('RemoteName '+colItem.RemoteName);
Writeln('RemotePath '+colItem.RemotePath);
Writeln('ResourceType '+colItem.ResourceType);
Writeln('Status '+colItem.Status);
Writeln('UserName '+colItem.UserName);
Writeln;
end;
end;
begin
try
CoInitialize(nil);
try
GetWin32_NetworkConnection;
Readln;
finally
CoUninitialize;
end;
except
on E:Exception do
Begin
Writeln(E.Classname, ': ', E.Message);
Readln;
End;
end;
end.
WNetOpenEnum(RESOURCE_REMEMBERED,...)
(If you need to support Win9x, you probably have to fall back to NetUseEnum)