PeterBelow
Members-
Content Count
463 -
Joined
-
Last visited
-
Days Won
13
Everything posted by PeterBelow
-
Have you tried to build the program as a 64 bit executable? You also need the 64 bit version of MySQL of course.
-
Component names cleared in design package
PeterBelow replied to brk303's topic in Delphi IDE and APIs
As far as I know forms (all TCustomForm descendants in fact, including TDatamodule) are not meant to be added to design-time packages. If you want to make them reusable from other projects add them to the object repository instead, this way they are accessible from the File -> New -> Others dialog. -
View program flow and calls to help understand code?
PeterBelow replied to SteveHatcher's topic in General Help
Pascal Analyzer may be helpful in this context. It is not free but if I remember correctly you can evaluate it for a period until paying for it. Have not used it myself, though. -
If you do multiple passes over the file you can end up replacing bytes in a part you replaced in a previous pass, which is usually not what you want.
-
This approach only works if you have one single search/replace pair.
-
OK; i'm done with the example code. Find a small test project attached as a zip file. It contains a unit named PB.ByteSearchAndReplaceU that implements a class TByteSearchAndReplace that encapsulates all the code for this task. It compiles and runs but I have not checked that it does do the actual replacements properly, due to the lack of test data. I leave that to you, good luck. ByteS&R.zip
-
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.