Jump to content

Remy Lebeau

Members
  • Content Count

    2684
  • Joined

  • Last visited

  • Days Won

    113

Everything posted by Remy Lebeau

  1. Remy Lebeau

    One line of code not quite right

    What are you talking about? There are no "function headers" in Delphi. Are you trying to reply to me or to Pat Foley? I'm so lost now were this discussion is going...
  2. Remy Lebeau

    One line of code not quite right

    Really? You've shown enough code that demonstrates you know how to CALL functions. So, per the documentation, simply change BoolToStr(a) to BoolToStr(a, True), etc.
  3. Remy Lebeau

    One line of code not quite right

    Because they really are incompatible types. The '+' operator is not defined for Booleans. Read the documentation: https://docwiki.embarcadero.com/RADStudio/en/Expressions_(Delphi)#Operators So, you would have to convert the Booleans to Integer before using the '+' operator, then convert the result back to Boolean before using the 'not' operator, eg: MemoResult.Text := MemoResult.Text + ('not a: ' + BoolToStr(not Boolean(Ord(a) + Ord(b)))) + sLineBreak; Alternatively: MemoResult.Text := MemoResult.Text + ('not a: ' + BoolToStr(not ((Ord(a) + Ord(b)) <> 0))) + sLineBreak; On the other hand, your input expression does not match what your text says, which would be just this instead: MemoResult.Text := MemoResult.Text + ('not a: ' + BoolToStr(not a)) + sLineBreak; On a side note: you don't need all the extra parenthesis around your strings: MemoResult.Text := 'a: ' + BoolToStr(a) + sLineBreak; MemoResult.Text := MemoResult.Text + 'b: ' + BoolToStr(b) + sLineBreak; MemoResult.Text := MemoResult.Text + 'a and b: ' + BoolToStr(a and b) + sLineBreak; MemoResult.Text := MemoResult.Text + 'a or b: ' + BoolToStr(a or b) + sLineBreak; MemoResult.Text := MemoResult.Text + 'not a: ' + BoolToStr(not a) + sLineBreak; Yes. Read the documentation: https://docwiki.embarcadero.com/Libraries/en/System.SysUtils.BoolToStr There is an optional UseBoolStrs parameter that defaults to false. Simple set it to true instead. Yes, I did, eg: MemoResult.Lines.Add('a: ' + BoolToStr(a)); MemoResult.Lines.Add('b: ' + BoolToStr(b)); MemoResult.Lines.Add('a and b: ' + BoolToStr(a and b)); MemoResult.Lines.Add('a or b: ' + BoolToStr(a or b)); MemoResult.Lines.Add('not a: ' + BoolToStr(not a));
  4. Remy Lebeau

    Application Loading incorrect bpl

    Actually, that doesn't answer my question at all, so let me rephrase it... When the application begins, is the BPL being loaded automatically by Windows (are you seeing a standard system error message?), or is the BPL being loaded by the application's code using Delphi's LoadPackage() function and then displaying its own error message? Can you provide a screenshot of the error message? Did you check Windows' PATH environment to see if the Desktop folder is present in it and is before the BPL folder? The best way to ensure that the BPLs are being loaded only from the app's BPL subfolder is to load them manually in code using LoadPackage() specifying the absolute path to each BPL. If that is not an option, then the next best option is to make sure the BPLs are marked for delay-loading in the app's config and then call SetDllDirectory() or AddDllDirectory() at app startup to add the BPL subfolder to the DLL search path before the standard system search path.
  5. Remy Lebeau

    My sLineBreak is not working

    In your example, it would be better to use the Lines.Add() method rather than the Text property, then you don't have to worry about using sLineBreak at all, or wasting time and resources to read the Text, append to it, and assign it back. procedure TFormIncrementAndDecrement.ButtonShowValuesClick(Sender: TObject); var x, y: integer; begin x := 6; y := 7; MemoResult.Clear; MemoResult.Lines.Add('The value of x is: ' + IntToStr(x)); MemoResult.Lines.Add('The value of y is: ' + IntToStr(y)); end;
  6. Remy Lebeau

    Application Loading incorrect bpl

    Are you linking statically to the BPL at compile-time, or are you loading the BPL dynamically at runtime?
  7. Remy Lebeau

    Looking for a certain component

    You can use a standard TPanel, simply adjust its BevelInner and BevelOuter properties to mimic the sunken look you want. And, you can assign text to a TPanel like you can with a TLabel (or, just put a TLabel on the TPanel).
  8. Remy Lebeau

    TStringgrid how to automatically set the column widths

    Did you try debugging the code? Probably the global EditSeriesForm variable is nil. Since the code is inside of a method of the Form class, it should be using the method's own Self pointer instead of using the global Form pointer: Col_Width := Self.Canvas.TextWidth(Grid.Cells[Acol,i]); But, the code really should be using the StringGrid's Canvas instead of the Form's Canvas: Col_Width := Grid.Canvas.TextWidth(Grid.Cells[Acol,i]); Also, there is no reason for the Grid parameter to be marked as var, since the code is not changing which object the variable points at. Objects are passed around by pointer, and passing that pointer into the method by value instead of by var reference will work just fine in this situation.
  9. Remy Lebeau

    Should I just dive in to GUI programs?

    Maybe because the majority of end users are not console users, and the books want you to reach a larger userbase more quickly? Just speculating...
  10. Remy Lebeau

    What is this flashing message doing there?

    What about a short screen capture video? Well, they could search their source code for the word "calculating"...
  11. Remy Lebeau

    What is this flashing message doing there?

    Which version of the IDE are you using? Are you seeing the flash appear in the code editor, or in your program's UI? Can you get a screenshot of the flash?
  12. Remy Lebeau

    for loop variable value after the loop

    W1037 FOR-Loop variable '%s' may be undefined after loop (Delphi) Also see: What is The Loop Variable After a For Loop in Delphi?
  13. Remy Lebeau

    for loop variable value after the loop

    I just now checked, this code exists in TListColumn.DoChange() all the way back to at least Delphi 5 (that the oldest version I have VCL source code for)!
  14. Remy Lebeau

    Catch CM_VISIBLECHANGED send by ANY control in the form?

    Sorry, but you are not on the right track, not even close. You can't pass a message ID to SetWindowsHookEx() like you are doing. The 1st parameter expects a hook type (one of the WH_... constants), not a message ID. To hook window messages, you need to specify either the WH_GETMESSAGE or WH_CALLWNDPROC/RET hook type, and then look for your desired message ID inside of your hook callback function. However, in this particular situation, CM_VISIBLECHANGED is a private message to the VCL only, it does not go through the Win32 messaging system at all, so a SetWindowsHookEx() hook will never see it. The only way you can intercept CM_VISIBLECHANGED is to either: subclass the WindowProc property of every TControl you are interested in. derive your own UI classes that either override the virtual WndProc() or DefaultHandler() method, or define a 'message' handler for CM_VISIBECHANGED. use a detouring library, such as MSDetours, to hook into the non-virtual TControl.Perform() method directly (which is what the TControl.Visible property setter calls to send out CM_VISIBLECHANGED). This won't help you in this particular situation, but in general to retrieve the relevant HWND in a SetWindowsHookEx() hook: for WH_GETMESSAGE, the lParam is a pointer to a MSG structure, which has an HWND member. for WH_CALLWNDPROC, the lParam is a pointer to a CWPSTRUCT structure, which has an HWND member. for WH_CALLWNDPROCRET, the lParam is a pointer to a CWPRETSTRUCT structure, which has an HWND member.
  15. Remy Lebeau

    Get Class Properties by ClassName

    Why not use the ClassType instead of the ClassName? GetProperties(v_FDConnection.Params.ClassType); GetClass() only returns classes that are registered with RegisterClass(). Not all classes are registered. GetClass() returns nil if it can't find the requested class. You are not handling that possibility. You can't pass nil to TRTTIContext.GetType(). FindClass(), on the other hand, will raise an EClassNotFound exception if the requested class is not found.
  16. Remy Lebeau

    Enum modules return ONLY the application, no other packages

    What makes you think EnumModules() has anything to do with that list? It enumerate the modules that your compiled EXE is using at runtime. Not the modules that are installed in the IDE at design-time. If you want the list that is installed in the IDE, then you will have to manually read that list from the IDE's configuration in the Windows Registry. If you want the list that your EXE is compiled with, then such modules only exist if you compile with Runtime Packages enabled so the packages are used as external BPLs at runtime.
  17. Arbitrary components don't have a Parent. TComponent does not have a SetParent() method. So, unless CreateComponent() is using RTTI, it won't have any knowledge of your custom SetParent() method. And it certainly won't be able to call it since it won't have access to TMyParentComponent. Only TControl-derived components have a Parent. I expect CreateComponent() to check if the specified class type is a TControl descendant, and if so then cast the created object to TControl in order to set its TControl.Parent property, as well as its TControl.Left/Top/Width/Height properties (probably by calling TControl.SetBounds()).
  18. Remy Lebeau

    FindFirst : with network files it fails

    Yes, it does. And has done so for a VERY VERY LONG time, long before the "manifest file and a setting in the registry" you refer to ever existed. https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#win32-file-namespaces NTFS is such a file system, which has been supported since Windows 3.1, though long paths were not supported on it until Windows 95. MAX_PATH is an artificial limitation of the Win32 API, not of the file system. The more commonly referred documention about this is: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation The "manifest file and a setting in the registry" that you refer to simply allows an app to use such long paths without needing to use the "\\?\" prefix anymore.
  19. Remy Lebeau

    Enum modules return ONLY the application, no other packages

    Does your program use external DLLs/BPL files? Even if you are using Packages, if they are statically linked into your EXE then they will probably not be treated as separate modules.
  20. Good catch! Per RFC 7540: https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.4
  21. Remy Lebeau

    Pointer variable erros

    Because you are using it incorrectly. They are the same address, but they are not the same type. The Params is holding a ^^TParamEmbedded (a pointer to a pointer to a record), but ParamEmbeddedRec is a ^TParamEmbedded (pointer to a record) instead. The only reason your code even compiles at all is because the Params is an untyped Pointer, so all type safety is out the window. You are correct. You are storing a ^^TParamEmbedded into the Params, and then accessing it back out as a ^TParamEmbedded instead, eg: +------------+ +------------+ | Operacao | | PatchParam | | Params |---+ | Payoad | +------------+ | +------------+ ^ | ^ | | | +-------------+ | +---------------+ +------------------+ | ParamMaster | +-->| ParamEmbedded |<----| ParamEmbeddedRec | +-------------+ +---------------+ +------------------+ Get rid of the @, you don't need it since the ParamEmbedded variable is already a pointer, eg: procedure TForm1.Button1Click(Sender: TObject); Type TParamMaster = Record Operacao : Smallint; Params : Pointer; End; TParamEmbedded = Record PatchParam : String; Payload : String; End; Var ParamMaster : ^TParamMaster; ParamEmbedded : ^TParamEmbedded; ParamEmbeddedRec : ^TParamEmbedded; begin New(ParamMaster); New(ParamEmbedded); ParamEmbedded.PatchParam := 'somePatch'; ParamEmbedded.Payload := '{"aooCode": "F60EB930-9B1B-11EF-9657-02240D86274B"}'; ParamMaster.Operacao := 1; ParamMaster.Params := ParamEmbedded; // <-- NO @ HERE! ParamEmbeddedRec := ParamMaster.Params; ... Dispose(ParamEmbedded); Dispose(ParamMaster); end; +------------+ +------------+ | Operacao | | PatchParam | | Params |------->| Payload |<----------+ +------------+ +------------+ | ^ ^ | | | | +-------------+ +---------------+ +------------------+ | ParamMaster | | ParamEmbedded | | ParamEmbeddedRec | +-------------+ +---------------+ +------------------+ That being said, this example can be simplified by not using New/Dispose at all, in which case using @ does make sense, eg: procedure TForm1.Button1Click(Sender: TObject); Type TParamMaster = Record Operacao : Smallint; Params : Pointer; End; TParamEmbedded = Record PatchParam : String; Payload : String; End; Var ParamMaster : TParamMaster; ParamEmbedded : TParamEmbedded; ParamEmbeddedRec : ^TParamEmbedded; begin ParamEmbedded.PatchParam := 'somePatch'; ParamEmbedded.Payload := '{"aooCode": "F60EB930-9B1B-11EF-9657-02240D86274B"}'; ParamMaster.Operacao := 1; ParamMaster.Params := @ParamEmbedded; // <-- DO USE @ HERE! ParamEmbeddedRec := ParamMaster.Params; ... end; ParamMaster ParamEmbedded +------------+ +------------+ | Operacao | | PatchParam | +------------------+ | Params |---->| Payload |<----| ParamEmbeddedRec | +------------+ +------------+ +------------------+
  22. Do you have the same problem if you use the WinInet API instead of the WinHTTP API? In any case, at this point does it really matter if the status text is being returned or not? It is arbitrary text determined by the server, so you shouldn't rely on it for any kind of processing logic, only for logging at best. What is important is whether the status code works or not, and it sounds like it does.
  23. Yes, unless you have access to the server's private key. Which is why I also mentioned Fiddler, which acts as a proxy and can capture HTTPS.
  24. Then you should open a ticket with Embarcadero asking for that.
  25. Prior to Delphi 12, the Enum type for TShiftState is anonymous, so you can't declare a variable of that type, at least not directly. With the introduction of Inline Variables and Type Inference in Delphi 10.3, you can do so, but only if you initialize the variable at the same time you declare it, eg: var state := ssShift; This is exactly the kind of situation why several such Sets in the RTL have been re-written in recent versions to separate their Enum types from their Set types. TShiftState was re-written in Delphi 12, it now looks like this: TShiftStateItem = (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble, ssTouch, ssPen, ssCommand, ssHorizontal); TShiftState = set of TShiftStateItem; So, you can now declare a variable of type TShiftStateItem.
×