I've a question about High-DPI application in Delphi.
Surfing on the Internet I've found a series of articles published by Žarko Gajić. these articles speaks about create Delphi application ready for High-DPI.
The method describes works fine but, the author use it inside every single application; for example speaking about TSpeedButtons.
My question is this: there is a way to implement this kind of behaviour also into components? For example I'm realising a simple component that works like the Embarcadero TSpeedButton but using Transparent PNG images.
The images inside the component are loaded at design-time from some PNG images. I've a TObjectDictionary in which I register the buttons states: enabled, disabled and so on.It is declared in this way:
FGlyphs: TObjectDictionary<TGlyphState, TPicture>
In the application that use this component I load PNG images from the files that are 24 x 24 pixel. When I execute the application on a 4K monitor this images become very small.
If I apply the Žarko method all works well but in this way every application the use my component need to implement this solution.
How to implement it directly inside the component? I thought to implement it inside the SetGlyph procedure, that is like the following code, but I don't know if this is the right place.
procedure TNCRSpeedButton.SetGlyphs(Index: TGlyphState; Value: TPicture);
begin
FGlyphs.Items[Index].Assign(Value);
end;
TGlyphState is defined in this way:
TGlyphState = (gtEnabled, gtDisabled, gtDown, gtOver);
Eros
1) First of all you should enable option Enable High-Dpi in Project Option -> Application -> your target platform -> Manifest file. This option is available since Delphi 10 (Seattle).
2) if in W10 OS you have different Scale, you could calculate and run TWinControl.ScaleBy (available for Forms) for adjust window and all elements on one specific window.
See demo on https://github.com/KohrAhr/DelphiDemoPPI
Demo contain TToolButtons controls.
Related
In VCL I used TOpenPictureDialog for loading of image files because it's useful to see a preview when selecting from a long list of files. I also used it for loading my own binary file format by creating a class derived from TGraphic, overriding the load and draw functions and registering it with TPicture. Now I've moved to FMX and would like a similar preview, but there is no TOpenPictureDialog. My only alternative currently seems to be to create a custom form for loading these files, including the ability to browse folders, etc, which seems like a big job to replicate all the functionaly of TOpenPictureDialog. Before I do that I wonder if anyone knows of a pre-existing component that does this? I'd like to support Windows and OSX initially.
If I do end up making my own component, would it be easier to start from scratch or to derive from and extend TOpenDialog? It seems that TOpenDialog is just running the default Windows open dialog in Windows so it seems unlikely that I could do that.
This is one of the few things missing from FMX that is available in VCL.
In VCL, I could load a font from resource and without saving it I could use it from memory.
Here is the code I use and it works in VCL:
procedure TForm1.Button1Click(Sender: TObject);
var
ResStream : tResourceStream;
FontsCount : DWORD;
begin
ResStream := tResourceStream.Create(hInstance, 'MyResourceName', RT_RCDATA);
winapi.windows.AddFontMemResourceEx(ResStream.Memory, ResStream.Size, nil, #FontsCount);
ResStream.Free();
button1.Font.name := 'MySavedFontNameInResource';
end;
In Firemonkey I just changed button1.Font.name to button1.Font.family but unfortunately the font didn't change. So I think this code is not compatible with firemonkey.
So in Firemonkey, how can I load a font from resource and save it temporary to memory and use it directly from there?
Update:
I saw these pages: Install font in firemonkey, How to use external fonts?
According to Mr Ed 's answer, it seems that there is no solution for this problem in FMX. But maybe we could load the font if we install it before running the app. I tried almost everything but I still can't load the the font.
There is also StylesSettings.ssFamily : Boolean property in New Delphi and must be set to False to have custom font family working. The same with Size, Style and FontColor.
This may or may not help.
Disclaimer
This requires extra researching that I have not gotten around to yet, but I believe this to be a good starting point.
Link for the MSDN page :- Custom Font Collections
You need to use the WinAPI.D2D1 unit (you may need FMX.TextLayout and FMX.Canvas.D2D as well) to gain access to the DirectWrite API. You can use this to get at the DirectWrite factories which will allow you to define and load a font from disk.
Once you have the font loaded AFAIK it should then be available to the entire application and hopefully all of the firemonkey controls. Its entirely possible that firemonkey only enumerates fonts at application load though, so this may all be for naught.
As I said, this requires research that I have not gotten to yet, so may only work if you are also custom painting your control (which I will be) and might not be suitable as a result.
I think I have an answer, which was only possible because of a LOT of help by Roy Nelson of Embarcadero's support staff who pointed me in the right direction.
I have verified that this works with Berlin 10.1 (without the Anniversary Patch applied) on Windows 10, 64 bit but I don't guarantee that will will work on all compiler versions/Windows versions and any insight other people have to offer would be very interesting to hear.
First off, I think the (currently) insurmountable issue starts with trying to use AddFontMemResourceEx as that produces fonts that are not enumerable and for Firemonkey to convert an installed TrueType Font to a graphically rendered D2D font--which is what it actually uses--it has to first be able to find it.
Replacing AddFontMemResourceEx with AddFontResource with a temp font file you write from the resource solves that problem, but it's not enough. After it's installed you need to force the TextLayout rendering engine to rebuild its font list which you can do with calling two lines from the FMX.Canvas.D2D.pas unit.
UnregisterCanvasClasses; //this tells it to forget everything it knows
RegisterCanvasClasses; //this tells it to learn it again based on the current state of this system, which now includes our dynamically loaded font.
I've posted a test project on GitHub at https://github.com/TheOriginalBytePlayer/FireMonkey-Fonts for anyone who wants to try it out.
Basically you create a resource file with your fonts in it -- numbered from 0 to whatever -- replace the {$R assimilate.res} line in the FMXFontInstaller.pas, with the one you jut created, add this file to your project source and you theoretically should be good to go.
Ok, so I downloaded a .zip file of all different kinds of examples from embarcadero... the way the buttons look and among other things are completely different from when I just create an application within my Delphi 7. I believe these examples were made for or made at a new time... because the button look way different from the way the button when I put them on my application. the buttons from the example look very modern and sleek and have mouse over effects (This applies for all the examples..its not a custom component ) I was wondering I can get this effect in my own applications within Delphi 7.. I can do this by opening one of the examples and just erasing all the code... but that's not what im trying to do..im wondering how I can accomplish these styles.. how come the examples have these nice looking buttons and such..but when I make an app within D7 its much older looking and such..
I apologize if my question is hard to understand.. and I appreciate any help on this.
Thank you in advance.. I appreciate it.
If I understand your question correctly, you're asking about the native control appearance changes that were added by the addition of Windows Themes in Windows XP.
Delphi 7 supported themes by use of the XPManifest component, which does nothing but add a manifest to your application which tells Windows your app is theme-aware and therefore it should load a more recent version of the common controls library. You can find the XPManifest component in the VCL component palette on the Win32 tab, or simply add the XPMan.pas unit to your uses clause. Note that the themed drawing does not work for all controls (grids, for instance, are not drawn using themes, and IIRC neither is TSpeedButton - it's been a long time since I used D7, so I'm not sure exactly what is and isn't supported, but the support is limited).
Starting with Delphi 2007, there is built-in support for Windows Themes, which is available by default in new projects. It can also be enabled in older projects using a checkbox in the Project->Options->Application dialog.
(Of course the real answer is that if you want your app to have the features included in modern versions of Windows, you should upgrade from your Windows-95 era version of Delphi to one that is more recent.)
I'm looking for a free component that has simple image editing features like pan, zoom, selection with cursor, etc. I will use OpenCV in my project, but I don't want to struggle with implementing an imaging component that does those functions, I want to focus on only OpenCV. I don't need any effects, filter, etc. I only need a canvas surface like photoshop or ms paint. I can write a component from scratch that derives from TWinControl, but it will take my days, and bugs will be into the bargain. I've searched on Torry but I haven't find yet.
Graphics32 probably provides exactly what you need.
It comes with components that support layers, and there are some example applications to show how to use them.
It's totally free, open source, doesn't require external dll's, and it's fast. It works for both Delphi and FreePascal+Lazarus.
Note: the screenshots on the project page don't show any layer-stuff, but just pull the latest version from svn, and check out the "layers" folder under examples. There are 3 demo's under there.
In an Delphi MDI application i can use the Tile,Cascade and ArrangeIcons procedures to organize my child windows, this methods only works when the FormStyle property is set to fsMDIForm, How i can produce the same effect in an SDI application, i mean how i can organize my open windows in a non MDI application?
Usually, you don't have to. Users who wish to re-arrange the windows can right-click the taskbar and choose the tile and cascade commands from the context menu. And I've seen TV commercials for Windows 7 showing that you can even just drag windows in a certain way to make them arrange themselves.
If you still want to provide the command yourself, use the TileWindows and CascadeWindows API functions.
You would have to organize them manually by looping through the TScreen::Forms[] list adjusting the Left/Top properties as needed.