Jump to content

PeterBelow

Members
  • Content Count

    442
  • Joined

  • Last visited

  • Days Won

    12

PeterBelow last won the day on December 2 2023

PeterBelow had the most liked content!

Community Reputation

209 Excellent

2 Followers

Technical Information

  • Delphi-Version
    Delphi 11 Alexandria

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. PeterBelow

    Anonymous methods as interfaces

    But that's the way it currently works! Of course you can design your own interface + implementor that acts exactly like anonymous methods act now, but that would still not be the same implementation the compiler creates behind the curtain now.
  2. PeterBelow

    Hunting a unit reference

    But the compiler error message should pinpoint the uses clause the (now missing) unit appears in, no?
  3. It will work but there is no point in doing it this way. Declare LPointer as type PMyRec and work with that. Don't use C idioms with Delphi, that only confuses things.
  4. PeterBelow

    Simple LiveBindings usage questions

    If this is for VCL: I centralize such code by overriding the UpdateActions method of the form and updating the control states from there. Much easier than fiddling with multiple event handlers or live bindings.
  5. PeterBelow

    Delphi 12: MessageDlg doesn't show icons

    This has come up before. Microsoft changed the UI guidelines and now recommends to not show an icon for confirmation dialogs. D12's vcl.dialogs unit was modied accordingly.
  6. PeterBelow

    Toolbar + ToolButton + TitleBar flicking

    You should not show a dialog inside a BeginUpdate/EndUpdate block in my opinion. That may be the source of your problem and it also serves no purpose i can see here.
  7. PeterBelow

    BringToFront alternative

    You cannot, it is only possible for TWinControl descendants.
  8. PeterBelow

    Visually edit a custom component

    You cannot, subcomponents in a custom component are created in an overridden constructor. But there is an alternative: Create a new frame in the designer and place groupbox and edits on it. Save the frame unit (after changing the Name property of the frame to something descriptive), best into a folder where you stash code units you want to reuse in other projects. To use the frame in another project just add its unit to the project. A frame behaves much like a component, you can drop multiple instances of it on forms, panels or other containers. But it can also hold code like a form, in event handlers or methods, and this code is shared between all frame instances. You can modify properties of the controls on the frame in the designer for each instance separately.
  9. Well, there are many ways to approach such a project. Using 20 images and 20 buttons may look appropriate at first glance but you have already identified the problem of code duplication and it is not the only one. Even getting the layout riight may be more work than you think. If you have a number of identical objects think array, and for visual stuff think grid. If your target platform is Windows and you intend to use the VCL instead of the FMX framework I would use a TDrawGrid as the main UI. For the start and exit buttons use TButtons hosted on a TPanel aligned alBottom on the form. The TDrawgrid is placed above the panel and aligned alClient. With 20 images you probably want 4 rows of 5 images each, so set the rowcount and colcount to 4 and 5, respectively and the FixedColCount and FixedRowCount to 0. Add a handler for the grid's OnDrawCell event, that is where you place the code to draw button (for an image not uncovered yet) or image. Then you need a way to store the state (covered/uncovered) for each cell and an identifier for the image a cell is holding. To keep the info for a cell together the natural storage is a record, so add a type definition like this above the form class: type TGameCell = record ImageIndex: Integer; Uncovered: Boolean; end; The game state is then a 4x5 array of TGameCell: const CNumRows = 4; CNumCols = 5; type TGameState = array [0..CNumRows-1, 0..CNumCols-1] of TGameCell; Add a field to the protected section of the form class: FGameState: TGameState; Each element of the game state array corresponds to a cell in the drawgrid. OK so far. Now you need some storage for the images. The most appropriate is a TImageList, so drop one on the form, set its Height and Width to the size of the images you want to use and then load the images into the list. The index of a given image will be used to identify it in the TGameCell. I asume with 20 cells you will have 10 images. Set the defaultcolwidth and defaultrowheight properties of the grid to values a bit larger than the images, say 4 pixels more. That gives you spacing between the tiles you have to draw. OK so far. Add a handler to the form's OnCreate event. There you place the code to initialize the FGameState array. The Uncovered members of the TGameCell records will start out as false, so you only need to set the ImageIndex to specify which image to show in each cell, using the index from the imagelist. That is the basic setup. Now you have to figure out how to draw the cells to resemble the usual memory game card. The event handler for the grid's OnDrawCell event has the following parameter list: procedure (Sender: TObject; ACol, ARow: Longint; Rect: TRect; State: TGridDrawState) Sender is the grid, you will have to draw on its Canvas, so add a variable for that to the handler sceleton the IDE created for you: var LCanvas: TCanvas; begin LCanvas := (Sender as TDrawgrid).Canvas; ACol and ARow tell you which cell to draw and, conveniently, these directly correspond to the matching TGameCell indices in FGameState. If you leave the DefaultDrawing property of the grid at the default True the VCL will have already drawn the cell background, so you can concentrate on drawing the image or button. Which it is you determine by looking at FGameState[aRow, aCol].Uncovered. If true you use the imagelists Draw method, passing it the LCanvas and the Left and Top members of the Rect parameter, adding 2 for the spacing to both. To draw the button the simplest way would in fact be to add a suitable image to the imagelist as well and draw it the same way. An alternative would be the DrawFrameControl Windows API method, but that is much more complicated to use. OK, so the form will now show the grid when you run the project (at designtime the grid is empty). Now you need to detect clicks on the cells, so add a handler to the grid's OnMouseDown event. Its X and Y parameter tell you where the mouse went down inside the grid but not which cell that is. Fortunately the grid has a MouseToCell method, so call that to get the cell, look at the Uncovered member of the corresponding TGameCell. If true exit directly, if false set it to true and call the grid's Invalidate method to get it to redraw. This would also be the place from which you then evaluate the game state, i. e. see if this action has uncovered the mate to the last tile uncovered (if so stop the timer), has uncovered the first tile (if so remember the cell coordinates and start the timer), and so on. If the timer fires you would just set both cells to Unconvered:= false, stop the timer, and Invalidate the grid to redraw. OK enough loafing around! Now get to work
  10. PeterBelow

    ISAPI and regedit

    What root key do you use? HKEY_CURRENT_USER depends on the user running the process in question (IIS probably) and that may not be what you expect. And which access rights do you specify when you try to open the key in question?
  11. Well, it may work but I fail to see the usefulness of such a construct.
  12. PeterBelow

    What new features would you like to see in Delphi 13?

    Because classes are reference type and records are value types. A variable/field of a reference type will always have a a known size, sizeof(pointer). A value type does have the size defined by the type and that would be unknown at the point of the foreward declaration. A one-pass compiler cannot handle that.
  13. Generics in Delphi don't work the way you seem to think they do. To use the generic type T inside a method of the generic class with a specific type the compiler needs some minimal information on what T can be. That is what generic constraints are for. Unfortunately the constraints supported at the moment are quite limited and will not cover what you intend to do.
  14. PeterBelow

    Do runtime created forms close the TFDQuery connections?

    All components that have the form as Owner (which includes all components dropped on the form in the IDE designer) are automatically destroyed when the form is destroyed. So your query components are destroyed but whether that automatically releases serverside resources depends on how the component, especially its destructor, is implemented. But a TFDQuery will close the query when it is destroyed, so your scenario is OK.
  15. PeterBelow

    Two strange probems in D11 (code+video)

    One thing may be a problem. Both the cmtx22 and cmtx33 functions use a (global ?) variable cmtx but do not clear it first. So the array elements not set by the functions will have values carried over from previous uses of this variable. Sorry, but the whole design looks fishy and error prone to me and seems to use plain procedural programming 40 years out of date. You define a large fixed size array type, variables of which will not only waste a lot of memory for elements never used, but you also have no convenient way to figure out from a variable what the dimensions of the actually used part are. In my opinion you should build a TConfusionMatrix class, which internally uses a 2D dynamic array (array of array of extended) to store the values of the matrix. The constructor of the class would take the needed dimension and size the internal array accordingly. You could have additional constructors to build the matrix from your string representation or a 1D array of values, methods to return a string representation, to compare an object of the class to another, properties to return the dimensions of the matrix or to get or set element values. Since the matrix object knows the size of the internal array it would be easy to check report indexing errors and so on.
×