PatV
Members-
Content Count
39 -
Joined
-
Last visited
Everything posted by PatV
-
Hi All,, Just a silly question 🙂 if I can write this code, what is the pros and cons about it ? From a lasy view, you don't need to create it, free it, .. Thanks Patrick prTxt = ^rTxt; rTxt = record private FValue : string; function GetAsText : string; public property Value : string read FValue; property AsText : string read GetAsText; function WithValue(const aValue : string) : prTxt; end;
-
Yes Darnocian, it was the goal, add fluent interface to record, so the main difference is that passing a record is a copy compare to a class Thanks Patrick
-
Hi David, Thanks for your reply ; that's both function (and btw working) { rTxt } function rTxt.GetAsText: string; begin result:=StringReplace(FValue,'\r\n',CRLF,[rfReplaceAll]); end; function rTxt.WithValue(const aValue: string): prTxt; begin FValue:=aValue; result:=@Self; end; How should I write it then ?
-
Delphi 11.0 Hi All, I would like to have an advice on how can I get this class more useful, I'm annoying with the 'set of ..' and the property of the set. Is there a way to change this class so I can use it with other 'set of' without recreate a similar class to resume, be able to change SOTTypeOfProperties and TTypeOfProperties so I don't need to rewrite a specific class for a different type of set Thanks Patrick SOTTypeOfProperties = Set of TTypeOfProperties; TFPropertiesCpt = class (TInterfacedObject,IFCompteurUpdate) private FItems : TDictionary<integer,rCompteurUpdate<TTypeOfProperties>>; FProperties : SOTTypeOfProperties; procedure ResetCompteurs; procedure InitList; procedure SetMax(const aValue : integer); procedure Duplicate(const aValue : TFPropertiesCpt); public constructor Create; destructor Destroy; override; property Items : TDictionary<integer,rCompteurUpdate<TTypeOfProperties>> read FItems write FItems; property Properties : SOTTypeOfProperties read FProperties; function Add(const aTypeOf : TTypeOfProperties ; const aInc : integer = 1) : TFPropertiesCpt; function WithInit : TFPropertiesCpt; function WithInfo(const aValue : TTypeOfProperties ; aProc : TProc) : TFPropertiesCpt; function WithMax(const aValue : integer) : TFPropertiesCpt; function ResetCompteur(const aValue : TTypeOfProperties) : TFPropertiesCpt; overload; procedure Execute; function AllDone : boolean; class function Clone(const aValue : TFPropertiesCpt) : TFPropertiesCpt; end;
-
Reorganize a class / Set Of ..
PatV replied to PatV's topic in Algorithms, Data Structures and Class Design
Thanks a lot Peter, it was the answer I was searching for. Regards Patrick -
Reorganize a class / Set Of ..
PatV replied to PatV's topic in Algorithms, Data Structures and Class Design
Thanks to all, I'll try to correct my post. Patrick -
Reorganize a class / Set Of ..
PatV replied to PatV's topic in Algorithms, Data Structures and Class Design
ok, sorry, for me it was a class ... not an interface TFPropertiesCpt = class (TInterfacedObject,IFCompteurUpdate) -
Hi All, I'm trying to get message in my main thread from a task inside a procedure inside a pipeline without success. FPipeline := Parallel.Pipeline; FPipeline.Stage(AccountsGl_SearchSuggested) .Stage(AccountsGl_TryGet , Parallel.TaskConfig.OnMessage(TaskMessage)) .Run .Input.Add(TOmniValue.FromArray<rImport>(Items)); FPipeline.Input.CompleteAdding; In my procedure AccountsGl_TryGet I have this ; procedure TFImport.AccountsGl_TryGet(const input, output: IOmniBlockingCollection; const task: IOmniTask); var aValue : TOmniValue; begin for aValue in input do begin if task.CancellationToken.IsSignalled then break; AccountGl_GetSuggested(aValue.ToRecord<rImport>); end; end; and in AccountsGL_GetSuggested I have procedure TFImport.AccountGl_GetSuggested(const aSearch : rImport); var iTask : IOmniTaskControl; begin iTask := CreateTask(WorkerGetAccountSuggested, clsConnectionPool.GetTGUIDString ) .OnMessage(TaskMessage) .OnTerminated(TaskTerminated) .SetParameter('Msg' ,MSG_GET_ACCOUNTSUGGEST) .Schedule(FDbPool); end; from workerGetAccountSuggested I have the following call if not task.Terminated then begin aOVValue := TOmniValue.FromRecord<rAccountGl>(aValue); task.Comm.Send(task.Param['Msg'],aOVValue); end; So, the message ( task.Comm.Send(task.Param['Msg'],aOVValue) ) from iTask in the procedure AccountsGL_GetSuggested never achieve the TaskMessage procedure. Do you have any clues ? Regards Patrick
-
Hi All, I'm searching a way to remove the Tag 'Inbox' from message. I try to send command, via IdImap4.SendCmd('C1','UID STORE '+rMess.UID+' -X-GM-LABELS ("Inbox")',['OK','BAD','NO'], true); Without success. Any clues ? Regards Patrick
-
Thanks a lot for the explanation Remy ! Patrick
-
Hi Remy You are right about the extra spaces, I've got another message, now. S:C1 UID STORE 193 -X-GM-LABELS (\Inbox) R:C1 BAD UID STORE not allowed now. If found also the link you mentioned How to remove a label from an email message from Gmail by using the IMAP protocol? as this one too on witch you have replied. what-belongs-in-aexpectedresponses-parameter-to-tidimap4-sendcmd I've tried also the "move" command but I didn't get the good UID, my goal was to read messages header through RetrieveHeader, and move later message selected on a TVirtualStringTree, but It seems that once I close the imap connection, those uid are no more correct. IDImap4.SelectMailBox('INBOX'); IDImap4.SearchMailBox(aSearchInfo); iUID:=0; with IDImap4 do for i:=0 to High(MailBox.SearchResult) do begin iMsg:=TIdMessage.Create; iMsg.Clear; RetrieveHeader(MailBox.SearchResult[i],iMsg); sUID:=IntToStr(MailBox.SearchResult[i]); iUID:=MailBox.SearchResult[i]; rMess.WithMessage(iMsg).WithUID(sUID).WithNode(Nil).asUnSelected; AnArray.add<rMsg>(Msgs,rMess); end; FillVST; IdIMap4.Disconnect; I'll test the function tomorrow. IdImap4.UIDStoreValue(rMess.UID, sdRemove, 'X-GM-LABELS', '\Inbox'); Thanks again Patrick
-
Hi Remy, Thanks for your component and your support, I've tried it also and get an error too. IdImap4.SendCmd('UID STORE ' + rMess.UID + ' -X-GM-LABELS (\Inbox)', ['OK','BAD','NO'], true); S:C1 UID STORE 189 -X-GM-LABELS (\Inbox) R:C1 BAD Could not parse command IdImap4.UIDStoreValue(rMess.UID, sdRemove, 'X-GM-LABELS', '\Inbox'); I didn't look at this function, I'll go with it Thanks Patrick
-
Help with dynamic record memory leak
PatV replied to Gary's topic in Algorithms, Data Structures and Class Design
Hi You can still use record and forget pointers TReminderItem = record FEmployeeID: Integer; FEmployeeName: String; FHireDate: TDate; FLastDate: TDate; FNotes: String; end; PReminderItem = ^TreminderItem; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private procedure GetReminder(AList: TList<TReminderItem>); { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var LList : TList<TReminderItem>; LReminderItem : PReminderItem; begin LList := TList<TReminderItem>.Create; try GetReminder(LList); ShowMessage(Format('Name: %s', [LList[0].FEmployeeName])); finally // for LReminderItem in LList do // Dispose(LReminderItem); LList.Free; end; end; procedure TForm1.GetReminder(AList: TList<TReminderItem>); var LReminderItem : TReminderItem; begin // LReminderItem := TReminderItem.Create; LReminderItem:=default(TReminderITem); with LReminderItem do begin FEmployeeID := 1; FEmployeeName := 'Test Name'; FHireDate := Now; FLastDate := Now; FNotes := 'A Note'; end; AList.Add(LReminderItem); end; -
Just released eBook: Delphi Event-based and Asynchronous Programming
PatV replied to Dalija Prasnikar's topic in Tips / Blogs / Tutorials / Videos
Hi Dalija, I've got your book, congrats, it is very helpful !!! Patrick -
Hi All, I'm using Parallel.Async to send an email, even if it's working, I would like to know if my approach is correct ; procedure TTFrmPanelPrint.SendMailParallel; var sRacine : string; sFrom,sName,sSubject,sBody : string; begin sRacine:=TPath.Combine(FReport.Directory ,FReport.FileName); sFrom := rUser(FReport.Print.Values[pspUser]^).Mail.GetMail; sName := rUser(FReport.Print.Values[pspUser]^).Name.FirstLastName; sBody :=Comment.Lines.Text; sSubject:= FFile.External; end; Parallel.Async ( Procedure(const task : IOmniTask) function AddAttach(const aRacine : string) : TStringList; var sFile : string; begin Result:=TStringList.Create; Result.Add(aRacine+cExtPdf); Result.Add(aRacine+cExtXlsx); for sFile in LBAttachments.Items do Result.Add(sFile); end; var sAttach,sTo,sBC,sCC : TSTringList; begin sAttach := AddAttach(sRacine); sTo :=TStringList.Create; sCC :=TStringList.Create; sBC :=TStringList.Create; sTo.Add(CbCommunication.Text); Task.Invoke ( procedure begin FMail.WithFrom(sFrom) .WithFromName(sName) .WithTo(sTo) .WithSubject(sSubject) .WithBody(sBody) .WithAttachments(sAttach) .WithPrcMailLog(LogAdd) .WithPrcOnDone(MailSendDone) .Send; sTo.Free; sCC.Free; sBC.Free; sAttach.Free; end ) end ); end; Thanks a lot Patrick
-
Sending Email via GMail Using OAuth 2.0 via Indy
PatV replied to Ugochukwu Mmaduekwe's topic in Indy
@Geoffrey Smith Thanks a lot for your sample on Github Patrick -
I'm working with Delphi 10.3.3 Hi all, does anyone have an idea for a project like this ; On a desktop, a software (master), and on a tablet (let's says surface) the slave. I would like to send the PDF or whatever from the master to the slave on runtime. What's the best approach to communicate between the 2 ? A thread communicating with a database ? or a communication channel between the master / slave ? Thanks Patrick
-
Thanks I will look at. I really don't know if I'll play with Tcp/Ip Socket or something else.
-
Delphi 10.3.2 TVirtualStringTree V 7.2.1 Hi All, I'm searching to add multiline to the header of a TVistualStringTree, does it exist already or do I need to use ownerdraw ? Thanks Patrick
- 1 reply
-
- tvirtualstringtree
- vcl
-
(and 2 more)
Tagged with:
-
found .. set coWrapCaption to True to the TVHeader.Columns[x].Options
- 1 reply
-
- tvirtualstringtree
- vcl
-
(and 2 more)
Tagged with:
-
Hi all, Is it possible I have a race condition in a thread pool ? when I launch a task, I get a database connection from my database factory, but when the worker want to use it, Sometimes I've got an error message "mysql server has gone away", if I'm retrying after few sec, I didn't get the error message again, everything is working. Is there a specific status that a Thread from the thread pool is going to be destroyed ? Thanks Patrick FPoolSearch is definined as iOmniThreadPool; procedure TFrameCustomer.SearchForId(aValue : integer); var Params : TParameters; const cParam = 'I_IDCLI'; begin WithParamsReset(Params); WithParam(Params,cParam, aValue ,dtInteger); CreateTask(WorkerSearchId, GetTGUIDString ) .OnMessage(TaskMessage) .OnTerminated(TaskTerminated) .SetParameter('Params',TOmniValue.FromArray<rParameter>(Params)) .SetParameter('ProcName','prc_ClientSearchId') .Schedule(FPoolSearch); end; {------------------------------------------------------------------------} procedure WorkerSearchId(const task: IOmniTask); function FillData : TFCustomer; var aCust : TFCustomer; begin result:=TFCustomer.Create; with (task.ThreadData as TConnectionPoolData) do begin with DM.Proc do // Datamodule . Procedure begin WorkOnParams; // Inject parameters from the procedure Open; if RecordCount>0 then FilInfo(result,task); end; end; end; var aOVValue : TOmniValue; aRes : TFCustomer; begin (task.ThreadData as IConnectionPoolData) .WithProcedureName(task.Param['ProcName']) .WithParameters(task.Param['Params']); aRes := FillData; aOVValue := TOmniValue.CastFrom<TFCustomer>(TFCustomer.Clone(aRes)); aRes.Free; task.Comm.Send(MSG_SHOW,aOVValue); end;
-
ok, will check for Thanks PAtrick
-
setthreaddatafactory Passing parameter to ThreadDataFactory
PatV posted a topic in OmniThreadLibrary
Delphi 10.3 Omnithead 3.07.5 Hi All, I'm just a little lost, I would like to pass parameters to the data factory, I know I can pass function like this TOTPThreadDataFactoryFunction = function: IInterface; TOTPThreadDataFactoryMethod = function: IInterface of object; and my function is like {-------------------------------------------------------------------------------------------------} function TFConfig.CreateThreadPool(aHandle : THandle ; aConfig : rConnectionConfig ; aValue: string) : iOmniThreadPool; var iOmniValue : TOmniValue; begin iOmniValue := TOmniValue.FromRecord<rConnectionConfig>(aconfig); result := otlThreadPool.CreateThreadPool(aValue); result.MaxExecuting := result.NumCores; result.SetThreadDataFactory ( (function (aHandle : THandle ; aConfig : TOmniValue) : IInterface begin result:=Function : IInterface begin result:= ?? end; end )(aHandle,iOmniValue ) ); end; {-------------------------------------------------------------------------------------------------} rConnectionConfig is a record containing info on to be able to connect to the datamodule RConnectionConfig = record User : string; Password : string; Database : string; Protocol : string; Port : integer; HostName : string; LibraryLocation : string; ModuleName : string; end; Could someone help me with this Thanks Patrick -
setthreaddatafactory Passing parameter to ThreadDataFactory
PatV replied to PatV's topic in OmniThreadLibrary
Working :-) Thanks again Primož -
Hi, could someone tell me what's wrong here, I'm returning an IInterface as needed so ... [dcc32 Error] clsInit.pas(313): E2250 There is no overloaded version of 'SetThreadDataFactory' that can be called with these arguments ( in OtlThreadPool ; TOTPThreadDataFactoryFunction = function: IInterface; ) function TFConfig.CreateThreadPool(aHandle : THandle ; aConfig : rConnectionConfig ; aValue: string) : iOmniThreadPool; begin result := otlThreadPool.CreateThreadPool(aValue); result.MaxExecuting := result.NumCores; result.SetThreadDataFactory ( function : IInterface begin result:=CreateConnectionPoolData(aHandle,aConfig); end ); end; I have defined CreateConnectionPoolData as follow function CreateConnectionPoolData(const aHandle : THandle ; const aConfig : rConnectionConfig) : IInterface; var aPool : IConnectionPoolData; begin aPool := TConnectionPoolData.Create; aPool.WithHandle(aHandle).WithConnectionConfig(aConfig); result:=aPool; end; IConnectionPoolData = interface function WithHandle(const aValue : HWND) : IConnectionPoolData ; function WithConnectionConfig(aValue : rConnectionConfig) : IConnectionPoolData ; end; Thanks Patrick