PeterBelow
Members-
Content Count
508 -
Joined
-
Last visited
-
Days Won
13
Everything posted by PeterBelow
-
Possible changes to string/char handling in Delphi 11(.2)?
PeterBelow replied to omnibrain's topic in General Help
That is the source of your problem because converting an AnsiChar to UnicodeChar ( = Char) is not a simple byte copy, it will convert characters not in the 7 bit ASCII set to Unicode codepoints that may have different ordinal values. This depends on the active ANSI codepage of the system as well. The only sensible solution is to treat bytes as bytes and not as characters, use TBytes or other suitable containers to store sequences of bytes instead of strings (ANSI or Unicode). Writing a Pos equivalent for TBytes is easy and there are likely dozens of implementations around, you just have to find one . -
You should have given us this info in your first post since it is very relevant to the way this needs to be approached. If the whole file does not fit into available process memory you have to process it in chunks, and this opens a whole new can of worms (only a chicken would be happy about that ). You have to deal with source byte sequences exceeding the end of a chunk, for example. And do you really want to do the replacement directly on the original file, potentially risking to corrupt it if something goes wrong? Anyway, I don't have time today to whip up any coding example, so be patient. P.S. : No PM unless explicitely requested! This forum is also intended as an information source for future problems from other people.
-
What the Delphi 11 version number after november patch ?
PeterBelow replied to William23668's topic in Delphi IDE and APIs
Mine shows 28.0.46481.1287. -
How large is the file you are trying to load? Did you build for a 32 or 64 bit platform? Try the latter.
-
D11 actually accepts initialized TBytes arrays in typed constants, so yo can do this: procedure ReplaceBytesInFile(aStream: TMemoryStream; const aSearchBytes, aReplaceBytes: TBytes); var LNumBytes: Integer; LPos, LEnd: PByte; begin LNumBytes := Length(aSearchBytes); Assert(LNumBytes = Length(aReplaceBytes), 'Arrays have to be of the same length!'); if LNumBytes = 0 then Exit; LPos := aStream.Memory; LEnd := LPos; Inc(LEnd, aStream.Size - LNumBytes ); while LPos < LEnd do begin if LPos^ = aSearchBytes[0] then begin if CompareMem(LPos, @aSearchBytes[0], LNumBytes) then begin CopyMemory(LPos, @aReplaceBytes[0], LNumBytes); // or // Move( aReplaceBytes[0], LPos^, LNumBytes ); Inc(LPos, LNumBytes); end else Inc(LPos); end else Inc(LPos); end; {while} end; type TDataRec = record SearchFor, ReplaceBy: TBytes end; const Data: array [0..1] of TDataRec = ( ( SearchFor: [$74, $00, $6f, $00, $7, $00, $73]; ReplaceBy: [$68, $00, $6f, $00, $7, $00, $73]), ( SearchFor: [$76, $00, $61, $00, $6F, $00, $70, $00, $5F, $00, $00]; ReplaceBy: [$00, $00, $61, $00, $6F, $00, $70, $00, $5F, $00, $00]) // add more data as needed, adjust array upper bound accordingly ); procedure TForm2.Test; var I: Integer; theFile: string; LBuffer: TMemoryStream; begin theFile := 'pathname here'; LBuffer := TMemoryStream.Create(); try LBuffer.LoadFromFile(theFile); for I := Low(Data) to High(Data) do ReplaceBytesInFile(LBuffer, Data[I].SearchFor, Data[I].ReplaceBy); LBuffer.SaveToFile(theFile); finally LBuffer.Free; end; end; Untested!
-
Please use your brain, its not just there to keep your head from imploding, you know . The code works for every byte sequence as long as both arrays are of the same length, so the total size of the data does not change.
-
Overlap JPG photo to oa background transparently
PeterBelow replied to Clément's topic in RTL and Delphi Object Pascal
If the background is indeed a single color you can treat that as transparent while drawing, using the TransparentBlt API function. You may have to convert the JPG to a TBitmap first, though. TBitmap has TransparentColor and Transparent properties, and a TImage with a TBitmap loaded also has a Transparent property that makes use of the TBitmap properties when rendering the image. If the background is not a single color you may have to preprocess the Tbitmap to turn pixels with colors "close enough" to clWhite to clWhite first. -
Windows VCL application pauses when window is not focused...
PeterBelow replied to DavidJr.'s topic in VCL
That cannot be unless you are doing something seriously wrong in you UI updating or your timer intervals are very short, so the UI has no time to repaint properly. We cannot diagnose this without seeing some code... -
Windows VCL application pauses when window is not focused...
PeterBelow replied to DavidJr.'s topic in VCL
The description sounds as if the UI thread does not process the timer messages in the expected fashion unless other messages are also in the message queue, in this case WM_MOUSEMOVE messages. This is not the normal behaviour of a Windows application. Add some logging to the timer events to check whether the events are triggered at the expected interval (OutputDebugStr should do if you run from the IDE). -
So what is the problem? The procedure takes an array of bytes, just feed it the correct one, e. g. var theFile: string; SearchFor, ReplaceWith: TBytes; begin SearchFor := [$74, $00, $6f, $00, $70, $00, $73]; ReplaceWith := [$68, $00, $6f, $00, $70, $00, $73]; ReplaceBytesInFile(theFile, SearchFor, ReplaceWith);
-
Since the replacement does not change the total size of the data you can load the file into a buffer suitable for binary data, do the replacement in this buffer and finally write it back to the file. A suitable buffer would be a TMemoryStream. The question is what these '.' bytes in your target string are. If these are actually zero bytes displayed as '.' in a hex viewer the target would be simply the UTF16 string 'tops', if these are real dot characters it would probably rather be the ANSI string 't.o.p.s'. You can probably answer that by looking at the byte following the 's', it should be 0 if this is UTF16 text. Let's assume it is, then the algorithm would be like this (untested!): procedure ReplaceBytesInFile(const aFilename: string; const aSearchBytes, aReplaceBytes: TBytes); var LBuffer: TMemoryStream; LNumBytes: Integer; LPos, LEnd: PByte; begin LNumBytes := Length(aSearchBytes); Assert(LNumBytes = Length(aReplaceBytes), 'Arrays have to be of the same length!'); if LNumBytes = 0 then Exit; LBuffer := TMemoryStream.Create(); try LBuffer.LoadFromFile(aFilename); LPos := LBuffer.Memory; LEnd := LPos; Inc(LEnd, LBuffer.Size - LNumBytes ); while LPos < LEnd do begin if LPos^ = aSearchBytes[0] then begin if CompareMem(LPos, @aSearchBytes[0], LNumBytes) then begin CopyMemory(LPos, @aReplaceBytes[0], LNumBytes); // or // Move( aReplaceBytes[0], LPos^, LNumBytes ); Inc(LPos, LNumBytes); end else Inc(LPos); end else Inc(LPos); end; LBuffer.SaveToFile(aFilename); finally LBuffer.Free; end; end; ReplaceBytesInFile(theFilename, TEncoding.Unicode.GetBytes('tops'), TEncoding.Unicode.GetBytes('hops') );
-
As far as I know the MS richedit common control does not support owner drawing at all, which is the reason why styling does not work for it. You could try to parse the rich text and modify the main color table in it before it is loaded, but I would rate that as a desparate measure; the RTF format is complex, to say the least. You could try to select larger blocks of text (e.g. lines or paragraphs) to find some with consistent text color; if your text is mainly the default color that may reduce the number of SelStart/SelLength calls needed to a managable number.
-
Have you tried to just set DefAttributes.Color before calling the inherited StreamIn method? SelAttributes.ConsistentAttributes may also be of use if you really need to manually correct the font color.
-
How can I add a option to my design time package to force it to be reloaded every time it is opened by any project?
PeterBelow replied to Al T's topic in Delphi IDE and APIs
I'm not sure I understand your requirement, but what you can do is this: With no project or project group loaded in the IDE, go to the Component -> Install packages menu. The appearing dialog list all design-time packages the IDE knows about (from the registry). Make sure package in question is not checked in the list. Close the dialog with OK. You may want to close and restart the IDE and call up the dialog again to vertfy that the package ist still unchecked. Now open the project in question, call up the dialog again and this time check the package. OK the dialog, do a save all for good measure. These steps should make sure the component package is only loaded for projects that explicitely want that. The project-specific package selection is stored in the project's DPROJ file. -
To be able to use a font on Windows it has to be installed (Font applet in the control panel or using the Windows font API, i. e. AddFontResourceEx). You have to do this on your user's systems as well, so have to distribute the font with your application.
-
This seems to be a limitation of the compiler, System.GetMem does use NativeInt for the size parameter, so can allocate more than 2GB for a 64 bit target. This works: procedure TForm2.Test; var p: pinteger; begin GetMem(p, NativeInt(High(Integer)) * Sizeof(Integer)); try Caption := Format('p= %p',[p]); finally FreeMem(p); end; end; The only problem is that you cannot declare a proper static array type for this memory block, so would have to do all the index calculations in code. However, you can size a dynamic array to more than 2GB: procedure TForm2.Test2; var a: array of integer; begin SetLength(a, High(Integer)); try Caption := Format('p= %p',[pointer(a)]); finally setlength(a, 0); end; end;
-
Anyone know if it's possible to have a Delphi Enterprise and Developer license on the same computer for two different versions?
PeterBelow replied to Al T's topic in Delphi IDE and APIs
No, all previous licences for higher editions will stay valid. -
Anyone know if it's possible to have a Delphi Enterprise and Developer license on the same computer for two different versions?
PeterBelow replied to Al T's topic in Delphi IDE and APIs
No, they are the same major version. If you wait for 12.0 to come out (no idea when that will be) it could coexist with 11.0 Enterprise. -
Anyone know if it's possible to have a Delphi Enterprise and Developer license on the same computer for two different versions?
PeterBelow replied to Al T's topic in Delphi IDE and APIs
Two different editions of the same Delphi/RAD Studio major version cannot coexist on the same PC, different editions of different major versions can, however. If you need the former you have to install one of the editions in a VM or different PC. -
Check duplicates in TADOQuery
PeterBelow replied to karl Jonson's topic in Algorithms, Data Structures and Class Design
Modify the SELECT statement for the query to include an ORDER BY clause for the code column. Then you can walk over the query result and just compare the current record's code to the one from the previous record (which you remember in a local variable in the loop). You can also formulate a SELECT statement that just returns the duplicates of course... -
The next thing to check would be whether the folder $(BDSLIB)\$(Platform) resolves to for your target platform ( should be C:\Program Files (x86)\Embarcadero\Studio\22.0\lib\android64 for an install using the default folders) is actually there, contains release and debug subfolders, and see if these contain the file(s) the error message moans about, e.g. system.classes.dcu and system.classes.o. I think that should be the file names. I have not installed Android platforms, so cannot check directly. If the files are there go and check the pathes in the specific project options, also check what path the BDSLIB environment variable resolves to.
-
check the Library path in the Tools -> Options dialog, Language -> Delphi -> Library page. It should start with $(BDSLIB)\$(Platform)\release. The "debug dcus" path on the same page should be $(BDSLIB)\$(Platform)\debug. Check this for every of the platforms you have installed (combobox at the top of the page).
-
Does only work if only one item can be selected from the group, but IO think in OPs case selecting both OptionOne and OptionTwo would be valid.
-
The hint system is designed to show a hint for a certain time when the mouse enters a control's real estate. In your case the mouse stays over the paintbox, so the hint is not shown again even if its value changed. Try to call Application.CancelHint after changing the value. And if you draw the gauge anyway, why not draw the value as well instead of using a hint window?
-
OnChange in Ribbon not working Well
PeterBelow replied to Zazhir's topic in Algorithms, Data Structures and Class Design
You have a timing issue here, the event fires before the page has become visible and the controls on it can be focused. The usual fix for such problems is to post (PostMessage) a custom message to the form and do the focus change in the handler for this message. There is also a OnTabVisibleChanged event for TRibbon, perhaps that fits better with your goal.