Mark Williams
Members-
Content Count
282 -
Joined
-
Last visited
Everything posted by Mark Williams
-
Sorry should have spotted that myself, although the help file in the StrUtils unit only refers to the functuion being deprecated for C++. I am now getting an "Ambiguous overloaded call to SearchBuf" error. I am calling SearchBuf in a functions declared as follows: Function FindWordInText(Const Text:PAnsiChar; Const FindText:AnsiString; caseSens, WholeW: boolean; index:integer):Integer; var P:PAnsiChar; Size:word; Options:TStringSearchOptions; begin {irrelevant code removed} P := SearchBuf(text, Size , 0, index, FindText, options); end; After changing my reference to strUtils in uses to AnsiStrings this would not compile. Reason being that TStringSearchOptions is in strUtils. So I also added StrUtils back in to my uses after AnsiStrings. As soon as I did so, I get the ambiguous error. The parameters passed into my function are correct for the SearchBuf function in AnsiStrings unit. I also get the same error if I add the AnsiStrings unit after StrUtils in my uses clause. If I change my functions parameters as follows: Function FindWordInText(Const Text:PWideChar; Const FindText:AnsiString; caseSens, WholeW: boolean; index:integer):Integer; var P:PWideChar; Size:word; Options:TStringSearchOptions; begin P := SearchBuf(text, Size , 0, index, FindText, options); end; It compiles and executes fine. Presumably, it is calling the StrUtils function. But why am I getting an ambiguous error with PAnsiChar as a parameter, but not PWideChar?
-
I have a very old project written in Delphi 5. Upgrade to RAD Studio not really possible at the moment due to work commitments. The project uses VirtualTreeView version 4.0.15 and includes various TVirtualStringTrees on various forms including the main form. I have made numerous small changes to the project in the last few weeks. I am now randomly getting errors when closing forms (including those which do not include TVirtualStringTree. The error arises from the freeing if tree nodes. No clue in the error report as to which treeview. I have tried to replicate the error by repeating the same steps to no avail. It is quite random. When the error arises the app has to be restarted. I assume the error is caused by some change I have made somewhere along the line, but I can't think what. I am trying to find a later version of VirtualTreeView for Delphi 5 in the hope that may fix the problem. Does anyone know what was the last version for D5 and where I can get it from? Also, can anyone think what may be causing random node freeing bugs in this way? I appreciate there could be many causes and I have provided hardly any info! But if anyone can think of anything that might be the cause it would be appreciated. Pulling out what little hair I have left!
-
Yes please
-
I have cloned the repository, but can find no reference to 2009. You mention cloning the "whole" repository. I guess I am not doing that. How do you get the whole repository from Github?
-
Because there are so many changes and the issue is random, I have been trying to avoid a bit by bit reversal, but it is looking as if I have no alternative!
-
Double-checked all tree code. The tree data does not link objects. They reference objectlists, but the tree data merely references an index to the objects in the objectlist. I've double-checked that I'm the object referenced by the index stored in tree data exists before attempting to refer to it. All that seems okay. I've also wrapped all freenode event code in try except. Still at a loss as to what is causing the problem.
-
I can only find as far back as 6.2.0, which does not appear to support Delphi 5
-
Googled Github Repository. No VTV in there. Any idea where I might find it I'll double check all tree data usage. Pretty sure there is nothing there that should cause problem, but could be wrong.
-
I'm using PDevMode to change printer settings. Printer.GetPrinter(Device, Driver, Port, hDMode); if (hDMode<>0) then begin pDMode := GlobalLock(hDMode); if pDMode <> nil then begin with pdMode^ do begin dmFields := DM_DEFAULTSOURCE; dmDefaultSource := ToBin; dmFields := dmFields or DM_PAPERSIZE; dmPaperSize := DMPAPER_A4; // Letter, 8-1/2 by 11 inches dmFields := dmFields or DM_PRINTQUALITY or DM_YRESOLUTION; if BestQuality then begin dmPrintQuality := LoWord(High_Quality); dmYResolution:=HiWord(High_Quality); end else begin dmPrintQuality := LoWord(Med_Quality); dmYResolution:=HiWord(Med_Quality); end; dmFields := dmFields or DM_DUPLEX; dmDuplex := DMDUP_VERTICAL; dmFields := dmFields or DM_COPIES; dmCopies := Copies; end; GlobalunLock(hDMode); This works fine if you only want to print one document or many documents with the exact same settings. But I am printing various documents in a loop and different document get printed at different qualities, with different nos of copies and to different bins. The problem is that once set the settings are saved and calling the above function does not change the settings for the new document. One code example I found suggests the following: Printer.GetPrinter(Device, Driver, Port, hDevmode); {force reset of devmode} Printer.SetPrinter(Device, Driver, Port, 0); Printer.GetPrinter(Device, Driver, Port, hDevmode); However, I then get a "Printer selected is not valid" error immediately I call Printer.BeginDoc. I'm not sure what else to do. Have tried Printer.Refresh which is no help. I've come up with a clunky temporary solution which is to change the PrinterIndex immediately after Printer.EndDoc and then set it back to the desired printer. It works in clearing the settings, but I'm sure it is not the best way to do this!
-
TFileStream fmShare modes
Mark Williams posted a topic in Algorithms, Data Structures and Class Design
I create/open a TFileStream in non-exclusive mode with the following code: if not FileExists(FileName) then //have to create it first and close it otherwise the share mode does not work!! begin Result := TFileStream.Create(FileName, fmCreate, fmShareExclusive); Result.free; end; Result := TFileStream.Create(FileName, fmOpenReadWrite, fmShareDenyNone); By my reckoning I should be able to open the file in read only mode: fs := TFileStream.Create(FileName, fmOpenRead, fmShareDenyNone); But it throws up an EFOpenError ie file in use by another process. I have looked online and found old posts which suggest that the share modes do not function for fmCreate mode ie always created exclusively and that is why I create, then close and then open. There was a post around 2010 which suggested the issue had been reported to Embarcadero and that it had been closed as fixed. Couldnt find anything much later than this. However as you can see , my problem is not with fmCreate, it is with fmOpenReadWrite. is there a bug with TFileStream or am I handling this in the wrong way? If there is a bug, does anyone know a work around? -
TFileStream fmShare modes
Mark Williams replied to Mark Williams's topic in Algorithms, Data Structures and Class Design
Thanks. I didn't read the help file properly! -
Within an ISAPI dll I create a pooled connection: Params := TStringList.Create; try Params.Add('DriverID=PG'); Params.Add('User_Name=*****'); Params.Add('UnknownFormat=BYTEA'); Params.Add('Pooled=True'); FDManager := TFDManager.Create(Nil); with FDManager do begin ResourceOptions.SilentMode:=True; ResourceOptions.AutoReconnect:=True; AddConnectionDef(FD_POOLED_CONN, 'PG', Params); Active := true; end; finally Params.Free; end; The server is left as the default ie localhost. The server is a machine on my local network (ip 192.168.0.12). It is also a web server with an external id (say 52.132.222.67) It hosts a number of databases and to change the referenced database I call the following: var Def : IFDStanConnectionDef; begin try Def : =FDManager.ConnectionDefs.FindConnectionDef(FD_POOLED_CONN); if Def.Params.Values['Database'] <> dbName then Def.Params.Values['Database'] := dbName; if assigned(Query) then Query.Close; if assigned(Query) then Query.ConnectionName := FD_POOLED_CONN; except on E: Exception do AddToLog('Error SetDatabase: '+e.Message, leMajorError); end; If I call the dll via the external ip address then my function to change the referenced database works just fine. If I use local ip it fails with the following error: Why do I get this error if I use the local ip, but not if I call the dll with the external ip and is there any way around it?
-
Problems changing database with pooled connection
Mark Williams replied to Mark Williams's topic in Databases
It has taken me an age to get back around to this, but I have finally uncovered the problem. It was not with FireDAC but my code. -
Using a Postgre database. If I run an insert query with the following code: # With FDQuery Do begin SQL.Text:='INSERT INTO temptab(email, name) ' +'VALUES (''email1'', ''name1''), ' +'(''email2'', ''name2'') ' +'returning id'; Open; end; The query returns two records containing the id for the newly inserted records. However, for larger inserts I want to use Array DML, but I also want to be get the returned data. Example code: With FDQuery Do begin SQL.Text:='INSERT INTO temptab(email, name) ' +'VALUES (:EMAIL, :NAME) returning id'; Params.BindMode:=pbByNumber; Params[0].DataType:=ftString; Params[0].DataType:=ftString; Params.ArraySize:=2; Params[0].AsStrings[0]:='Email1'; Params[1].AsStrings[0]:='Name1'; Params[0].AsStrings[1]:='Email2'; Params[1].AsStrings[1]:='Name2'; Execute(params.ArraySize); end; This returns no records. Not unsurprisingly as I am using the Execute command. If I change the Execute command to Open, it inserts just the first record from the array and returns the id for that new record. The Open function does not allow you to specify the ArraySize. I have tried to find some other procedure/property that will achieve this, but have drawn a blank. Does anyone know whether it is possible to return data from all inserted records using Array DML? If it is not possible can anyone suggest an efficient way for returning the inserted data? There seems to be two alternatives to me, neither of which is particularly attractive: Run a query to return all records that match the email and name and then extract the relevant ids. In large tables this would doubtless result in a significant overhead. Add an integer field to the table eg "temp_id". When inserting the data set this field to a unique value for all records inserted for the DML Array transaction and then retrieve the newly inserted data using "temp_id". Again, this doesn't appear to me to be an attractive solution. @Dmitry Arefiev If this is not currently possible with Array DML would you please consider including it for later versions?
-
FireDAC Array DML returning values from inserted records
Mark Williams replied to Mark Williams's topic in Databases
Good to know thanks, but would be a bit of a major shift for me from FireDac to Zeos -
FireDAC Array DML returning values from inserted records
Mark Williams replied to Mark Williams's topic in Databases
Sorry, I though I had posted the SO link. It is FireDAC Array DML and Returning clauses - Stack Overflow -
FireDAC Array DML returning values from inserted records
Mark Williams replied to Mark Williams's topic in Databases
Sorry I misunderstood. What is SA? -
It seems to me that the Embarcadero web site(s) are a complete mess. I manage to find a resource one day and it's gone the next. As examples, I was advised to use https://idera.secure.force.com/CG/ to get to Quality Portal. I managed to get in to the Portal earlier this year and make a feature request, I returned to view it today and when I click on the Quality Portal link, it wants my username and password again, but not the same one. It wants the username and password for the Registered Product Page. Incidentally, this page also has a link for Registered Product, which takes a lifetime to load and is out of date! I use this link https://members.embarcadero.com/Login.aspx?returnurl=http%3a%2f%2fcc.embarcadero.com%2fmyreg to access Registered Product, which works. However, the username and password I use to access Registered Product does not work for Quality Portal because it won't accept an email as a username it wants your "real" username and I have no idea what that is. Tried a couple of options and none of them work. Is it just me or is this a complete mess? And is it beyond the wit of man to put links for all resources we need on one consistent web page with one username and password?
-
Well I've not seen that site before today! Yes, it is annoying and pointless. I have made a note of the site for future reference. Of course, by the time I get around to looking at it, it will probably have moved somewhere else with n forwarding link.
-
FireDAC Array DML returning values from inserted records
Mark Williams replied to Mark Williams's topic in Databases
http://FireDAC Array DML and Returning clauses - Stack Overflow -
I'll probably be dead by then!
-
It's the same page as I get to via https://idera.secure.force.com/CG/. Still doesn't accept my credentials. But why all the different domains and different log ins required? It doesn't make any sense to me.
-
FireDAC Array DML returning values from inserted records
Mark Williams replied to Mark Williams's topic in Databases
It's a bit frustrating and I have also posted on Stackoverflow, but nothing has come back. I have logged a feature request at Quality Portal. I would give you the link, but for some reason my log in details no longer work. If you could comment on that to lend support that would be great. That's assuming you know how to get in to it. I tried today, but my details no longer work! -
Apologies in advance as this isn't really an Indy question, but not sure where else to ask it. I have written functions to batch parse information from emails. I would also like to be able to flag up possible suspicious activity such as date tampering. One of the things I am looking at is the difference between the date time in the Date header and the date time of the first Received header. If there is a significant difference between the two then I will flag the item as suspicious. However, I am not sure what would be a significant time difference to warrant flagging. Anything more than a few minutes strikes me as too long and my initial view is to opt for about 30 minutes. Views as to whether that sounds sensible would be appreciated.
-
It's not for filtering purposes. It is for a system that will store documents/resources including emails. When users are examining email threads I simply want to highlight that there may be something suspicious about one of the emails in the thread not exclude it from the thread. So if in 99% of the cases a Date header later than the Received header is suspicious that works for me. Perhaps my original question was unclear and answers have been given on the basis that I was looking to exclude such emails. Far from it, I am looking to highlight them. With that in mind perhaps I can ask my original question again. What sort of time difference by which the Date header is greater than the first Received header would you consider suspicious? I have opted for 30 minutes, but presumably there is an argument to say any difference is suspicious as I would expect most users' computers' and servers' clocks are automatically set.