Quantcast
Are you the publisher? Claim or contact us about this channel


Embed this content in your HTML

Search

Report adult content:

click to rate:

Account: (login)

More Channels


Showcase


Channel Catalog


Channel Description:

Blog entries categorized under Tips, Tricks and Techniques

older | 1 | .... | 6 | 7 | (Page 8) | 9 | 10 | newer

    0 0

    Release Notes:

    http://docwiki.embarcadero.com/RADStudio/Tokyo/de/10.2_Tokyo_-_Release_1

    Download ISO:

    https://cc.embarcadero.com/item/30786  (jedermann/frau) oder

    https://cc.embarcadero.com/Item/30785  (registrierte Benutzer)

    (Beide ISOs sind gleich.... )

    Download Webinstaller:

    https://cc.embarcadero.com/Item/30783

    Beschreibung / Neuerungen

    10.2 Tokyo – Release 1 ist ein Update für Delphi 10.2 Tokyo, C++Builder 10.2 Tokyo und RAD Studio 10.2 Tokyo, das für alle Kunden mit einem aktiven Update-Abonnement erhältlich ist.

    10.2 Tokyo – Release 1 enthält die folgenden neuen Leistungsmerkmale, Verbesserungen und Fehlerkorrekturen:

    • Leistungsverbesserungen für den Delphi-Linux-Server für RAD Server und DataSnap.
    • Updates für Delphi- und C++-Compiler und -Linker, die Probleme beim Laden von Packages, insbesondere beim Debugging, auf Windows 10 Creators Update beheben.
    • Unterstützung für die neuesten Versionen von iOS und Xcode (iOS 10.3 und XCode 8.3.2) für den iOS App Store.
    • FireDAC-Unterstützung für MSSQL 2012, 2014, 2016 und ODBC-Treiber 13.
    • Wichtige Verbesserungen für den C++-Linker für das Linken großer Projekte.
    • Korrekturen und Verbesserungen für die Laufzeitbibliothek und die VCL.
    • Weitere Android-Verbesserungen zu Rendering und Leistung von Steuerelementen und Korrekturen von Problemen mit TEdit bei Android N.
    • FireDAC-Unterstützung für Exclusive Isolation Level (EN) und Transaction Wait Time (EN) von InterBase 2017.
    • Korrekturen für mehr als 140 von Kunden in Quality Portal berichtete Probleme.

    Release 1 enthält auch Verbesserungen für "Tokyo Toolchain Hotfix" (veröffentlicht am 3. Mai 2017) und "Android Compatibility Patch" (veröffentlicht am 22. Juni 2017). Klicken Sie hier, um eine vollständige Liste der Features und Fehlerkorrekturen anzuzeigen.

    Hinweis: Das 10.2 Tokyo – Release 1 kann nur von Kunden mit einem aktiven Update-Abonnement heruntergeladen und installiert werden.

    Installation:

    De/Neuinstallation mit der Möglichkeit die Einstellungen zu behalten.


    0 0

    Frage: Ich habe das neueste Xcode installiert (hier: 8.3.3) und das Release 1 von Tokyo 10.2. Dennoch wird mir beim Importieren des SDKs nur angezeigt

    • iPhoneOS 10.3.1 bzw
    • MacOSX 10.12.4

    Mein iPhone/iPad/iOS-Gerät hat aber die iOS Version 10.3.3 bzw macOS ist auf Version 10.12.6.

    Das verwirrt mich!

    Antwort: Das verwirrt mich auch. Die Lösung ist aber relativ einfach: Die Xcode-Version korreliert nicht mit der iOS/macOS-SDK-Version. Es gibt zur Zeit kein neueres SDK innerhalb von Xcode (veröffentlichte Versionen). Auch, wenn sich die Betriebssystemversion (iOS/macOS) erhöht, heisst das nicht zwangsläufig, daß es eine neuere SDK Version gibt.

    Auf der Mac-Seite kann man das (im Terminal) schnell und leicht feststellen:

    Last login: Wed Aug  9 09:13:59 on ttys000
    MacBookPro:~ meissing$ xcodebuild -sdk -version

    Was eine solche Ausgabe erzeugt (gekürzt):

    iPhoneOS10.3.sdk - iOS 10.3 (iphoneos10.3)
    SDKVersion: 10.3
    Path: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk
    PlatformVersion: 10.3
    PlatformPath: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
    ProductBuildVersion: 14E8301
    ProductCopyright: 1983-2017 Apple Inc.
    ProductName: iPhone OS
    ProductVersion: 10.3.1
    
    MacOSX10.12.sdk - macOS 10.12 (macosx10.12)
    SDKVersion: 10.12
    Path: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk
    PlatformVersion: 1.1
    PlatformPath: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform
    ProductBuildVersion: 16E185
    ProductCopyright: 1983-2017 Apple Inc.
    ProductName: Mac OS X
    ProductUserVisibleVersion: 10.12.4
    ProductVersion: 10.12.4
    

    Also alles im grünen Bereich.

    Apple hat die Xcode/SDK-Versionen hier dokumentiert:
    https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html

    Ältere Xcode Versionen und die damit enthaltenen SDKs findet man hier:
    https://developer.apple.com/download/more/?name=Xcode

    Pro-Tipp: Im Ordner Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/ finden sich alle SDKs der installierten Xcode-Version (normalerweise nur eins). Hier kann man (unsupported! Apple möchte, daß man immer mit dem aktuellsten SDK entwickelt) auch ältere SDKs aus älteren Xcode Versionen unterschieben (dazu muss man das alte Xcode installiert haben und die SDKs aus diesem extrahieren (Time Machine, separater Mac, macOS-VM, Kollege, ...)


    0 0

    Delphi 10.2 では Linux 向けにサーバ用アプリを開発できるようになりました。そして開発には IDE から Linux 上でのリモート実行、リモートデバッグのために PAServer を使用します。PAServer は macOS / iOS アプリ開発でも使用しますが、Linux 向け開発が macOS / iOS アプリ開発と異なるのは「サーバ向けアプリ開発なのでアプリはGUIを持たない」ことです。従って作成したアプリへの入出力には stdin, stdout を使用することになります。


    しかし PAServer 経由の操作では PAServer 自体も stdin, stdout を使用していますので、PAServer 経由でリモート実行するアプリと標準入出力を取り合うことになります。

    これは少々不便なので、PAServer とは別のターミナルでアプリを実行することで、標準入出力の取り合いを回避する方法を説明します。


    0 0

    Frage: Ich nutze ein lokal installiertes InterBase. Ich möchte über Datenbankzugriffskomponenten darauf zugreifen. Aber sowohl FireDAC, als auch InterBase Express/IBX geben mir diese Nachricht:

    FireDAC:

    InterBase Express/IBX:

    Folgende Beobachtungen habe ich gemacht:

    • Das passiert nur in der IDE - In der IBConole kann ich auf die Datenbanken zugreifen
    • Die Dateien sind definitiv vorhanden
    • Benutzernamen und -kennwort habe ich richtig eingegeben
    • Stelle ich in IBX auf "Remote" um (mit "localhost") funktioniert es
    • Stelle ich in FireDAC auf "TCPIP" um (mit server=localhost) funktioniert es

    Wodran liegt das?

    Antwort: Das liegt wahrscheinlich an den Umgebungsvariablen in der IDE vom RAD Studio/Delphi/C++Builder. Es gibt zwei Variablen, die hier zum Tragen kommen und vom RAD Studio für die Verbindung genommen werden. 

    • INTERBASE - Das Verzeichnis der InterBase Installation; 
    • IB_PROTOCOL - Der Instanzname; normalerweise/default "gds_db". Dies ist auch hier weiter dokumentiert. Faktisch ist das die Port-Nummer default:3050) von InterBase

    Normalerweise sind diese nicht gesetzt; können aber (gerade bei Mehrfach-Instanzen von InterBase) das Ganze etwas durcheinander bringen. Man muss dann die Variablen setzen bzw ändern.

    Generell können die Variablen unter "Tools | Optionen | Umgebungsoptionen | Umgebungsvariablen" gesetzt werden. Normalerweise ist dies nicht nötig, da es nur eine Instanz von InterBase gibt, aber das RAD Studio/Delphi/C++Builder kann man für die Standardwerte hier anpassen

    INTERBASE
    C:\Program Files\Embarcadero\InterBase
    IB_PROTOCOL
    gds_db

    Nach dem Ändern der Umgebungsvariablen ist ein Neustart der IDE notwendig!


     

    Eine andere Möglichkeit für den "unavailable database" Fehler kann InterBase selbst sein: Wenn man die "Developer-Edition" benutzt, nimmt diese nach 48 Stunden keine Verbindungen mehr an. Ein Neustart des InterBase Servers behebt dann auch das Problem.

     


    0 0

    Frage: Ich möchte (aus welchen Gründen auch immer) für den aktuell angemeldeten Benutzer das ClearType von Windows ausschalten. Wie geht das?

    Antwort: ClearType lässt sich unter Windows 7/8/10 mittels ClearType-Textoptimierungs-Program (cctune.exe) über die Bordmittel von Windows ein- bzw ausschalten und konfigurieren:

    Dabei handelt es sich um eine Pro-User-Einstellung. Microsoft selbst stellt dafür den WinAPI-Befehl SystemParametersInfo bereit; mittels passender Aktion kann man hier das ClearType Verhalten beeinflussen.

    Quick-and-Dirty Lösung (bitte weiter lesen!):

    Ausschalten:

      SystemParametersInfo(SPI_SETFONTSMOOTHING,0,0,0);
      InvalidateRect(0, nil, True);

    Einschalten:

      SystemParametersInfo(SPI_SETFONTSMOOTHING,1,0,0);
      InvalidateRect(0, nil, True);

    Das jeweilige Absetzung von InvalidateRect(0, nil, True); erzeugt dabei einen kompletten Screen-Refresh....

    Die Original-Paramter sind

    BOOL WINAPI SystemParametersInfo(
      _In_    UINT  uiAction,
      _In_    UINT  uiParam,
      _Inout_ PVOID pvParam,
      _In_    UINT  fWinIni
    );

    Man kann, sollte das etwas besser gestalten

    Einschalten:

      SystemParametersInfo(SPI_SETFONTSMOOTHING, Cardinal(true), 0, SPIF_UPDATEINIFILE OR SPIF_SENDCHANGE);
      SystemParametersInfo(SPI_SETFONTSMOOTHINGTYPE, FE_FONTSMOOTHINGCLEARTYPE, 0, SPIF_UPDATEINIFILE OR SPIF_SENDCHANGE);

    Ausschalten:

      SystemParametersInfo(SPI_SETFONTSMOOTHING, Cardinal(false), 0, SPIF_UPDATEINIFILE OR SPIF_SENDCHANGE);

    Dadurch erreicht man beim Einschalten vier Dinge:

    • Cardinaltype wird richtig/leserlicher gesetzt
    • Durch SPIF_UPDATEINIFILE wird das auch persistent in der Windows-Umgebung gespeichert
    • Durch SPIF_SENDCHANGE wird auch gleich die Message zur Aktualisierung der Oberfläche gesendet (ein InvalidateRect ist nicht mehr nötig)
    • Durch eine zusätzliche "Action" SPI_SETFONTSMOOTHINGTYPE wird der Type des ClearType gesetzt (siehe MSDN-Doku-Link weiter oben)

    Beim Ausschalten erreicht man nur bessere/konformere Lesbarkeit und das senden der Window-Message zur Aktualisierung.

     

     


    0 0

    Zwei weitere Videos aus meiner Video-Tipp-Reihe:


    [YoutubeButton url='https://www.youtube.com/watch?v=EgZLt5l0mHM']

    [YoutubeButton url='https://www.youtube.com/watch?v=QbkuOluQw2k']

    0 0

    Using C++Builder 10.2 Tokyo, explain how to switch Wi-Fi on Android.

    Manage Wi-Fi switching using JWifiManager

    I use di_JWifiManager which wrapped WifiManager.
    di_JWifiManager is the Delphi interface.
    Set the variable. _di_JWifiManager f_WifiManager; use it like this.

    Required headers

    Header file for using WifiManager.

    #include <Androidapi.JNI.Net.hpp>
    #include <Androidapi.Helpers.hpp>
    #include <Androidapi.JNI.GraphicsContentViewText.hpp>
    #include <Androidapi.JNIBridge.hpp>
    

    Display design

    It is a design for displaying on Android.


    TEditTSwitchTTimerTLabel, was placed.

     

    When the main form creation

    Create _di_JWifiManager using TJWifiManager.

    //---------------------------------------------------------------------------
    void __fastcall Tfm_main_wifistatus::FormCreate(TObject *Sender)
    {
        //Form creation.Using TAndroidHelper, get the WIFI_SERVICE.
        _di_JObject obj = TAndroidHelper::Activity->getSystemService(TJContext::JavaClass->WIFI_SERVICE);
        if (obj != nullptr)
        {
            //Wrap to TJWifiManager.
            f_WifiManager = TJWifiManager::Wrap(_di_ILocalObject(obj)->GetObjectID());
            if (f_WifiManager != nullptr)
            {
                Timer1->Enabled = true;
            }
        }
    }
    

    Monitor Wi-Fi status at Timer1 event.

    void __fastcall Tfm_main_wifistatus::Timer1Timer(TObject *Sender)
    {
        //Use a timer event to monitor the Wi-Fi state.
        //Write state change to Edit1->Text. and It also reflects Switch1->IsChecked.
        Timer1->Enabled = false;
        if (f_WifiManager != nullptr)
        {
            Switch1->IsChecked = f_WifiManager->isWifiEnabled();
            UnicodeString wifistr;
            (Switch1->IsChecked)?wifistr = "true": wifistr = "false";
            Edit1->Text = "f_WifiManager->isWifiEnabled() = " + wifistr;
        }
        Timer1->Enabled = true;
    }
    

    When you tap the Switch1.

    Change the Wi-Fi status when tapping the Switch1.
    This uses the setWifiEnabled() function.

    void __fastcall Tfm_main_wifistatus::Switch1Switch(TObject *Sender)
    {
        //This is a Switch1 change event.
        Timer1->Enabled = false;
        //Set the value of Switch1->IsChecked to setWifiEnabled()
        f_WifiManager->setWifiEnabled(Switch1->IsChecked);
        TThread::CreateAnonymousThread([this]()
        {
            sleep(1);
            TThread::Synchronize(TThread::CurrentThread, [this]()
            {
                Timer1->Enabled = true;
            });
        })->Start();
    }
    

     

    https://github.com/mojeld/cpp_builder_firemonkey_wifi

     


    0 0

    Debug visualisers are a type of IDE plugin that allows you to change the display of a variable in the various debug windows (Local Variables, Watches, Inspector, and Evaluate/Modify.) For example, the TDateTime visualiser takes the double value that represents time and instead displays that time converted to a string. You register a debug visualiser for a type, so all variables of that type, and optionally descendants of that type, go through your visualiser.

    In previous versions, this type was specified by a plain string, such as 'TComponent', and there was no way to handle a generic type. If you registered 'MyGeneric<T>', the visualiser would never be called, because the concrete instantiations of that type do not use T - they might be 'MyGeneric<Integer>', 'MyGeneric<TButton>', and so forth.

    In 10.2.1, we have introduced support for registering a visualiser for a generic type. Your visualizer can implement IOTADebuggerVisualizer250 as well as the prior IOTADebuggerVisualizer, where the GetSupportedType method allows you to specify that the type string is a generic:

     

    .
      IOTADebuggerVisualizer250 = interface(IOTADebuggerVisualizer)
        ['{DC0C8D82-B783-4205-B3F4-D325BA8B3EEB}']
        { Return the Index'd Type.  TypeName is the type.  AllDescendants indicates
          whether or not types descending from this type should use this visualizer
          as well. IsGeneric indicates whether this type is a generic type. }
        procedure GetSupportedType(Index: Integer; var TypeName: string;
          var AllDescendants: Boolean; var IsGeneric: Boolean); overload;
      end;

    This means you can register for MyGeneric<T> and your visualiser will be called for all MyGeneric<>s. This is all generic types, ie interfaces as well as classes. 

    One note is that we do not yet support registering for descendants of a generic type, meaning that if you have MyDesc<T> = class(MyGeneric<T>) or MyDesc = class(MyGeneric<T>), you need to register a visualiser for MyDesc separately. This is because of some complexities in the internal evaluator.

    Generics are widely used, especially for collections like dictionaries and lists, and in third-party libraries like Spring4D. We hope you will find visualiser support for generics useful!

    Update: here is a code snippet demonstrating a template visualizer


    0 0

     

    Using ConnectivityManager with C++Builder

    With C++Builder 10.2 Tokyo Android ConnectivityManager class is available.
    Use the ConnectivityManager, you can get NetworkInfo
    NetworkInfo see various network information.
    inside that, The getType() function is Reports the type of network.
    The getType() function return is int.

    int type
    0x00000000 TYPE_MOBILE
    0x00000001 TYPE_WIFI
    0x00000006 TYPE_WIMAX
    0x00000009 TYPE_ETHERNET
    0x00000007 TYPE_BLUETOOTH

    I tried ways to get NetworkInfo.

    Declare _di_JConnectivityManager variable.

    _di_JConnectivityManager is the ConnectivityManager class interface.

     _di_JConnectivityManager    f_ConnectivityManager;
    

    It creates to use '_di_JConnectivityManager'.

    template <typename T1, typename T2> void __fastcall Tfm_main_wifistatus::getService(_di_JObject obj, T1& iobj)
    {
        if (obj != nullptr)
        {
            iobj = T2::Wrap(_di_ILocalObject(obj)->GetObjectID());
        }
    }
    void __fastcall Tfm_main_wifistatus::FormCreate(TObject *Sender)
    {
        //Form creation.Using TAndroidHelper, get the CONNECTIVITY_SERVICE.
        getService<_di_JConnectivityManager, TJConnectivityManager>(
            TAndroidHelper::Context->getSystemService(TJContext::JavaClass->CONNECTIVITY_SERVICE), f_ConnectivityManager);
    }
    

    Get the _di_JNetworkInfo using the getActiveNetworkInfo() function.

    //TJConnectivityManager::JavaClass->TYPE_WIFI;
    #define TYPE_WIFI 0x00000001
    //TJConnectivityManager::JavaClass->TYPE_MOBILE;
    #define TYPE_MOBILE 0x00000000
    //TJConnectivityManager::JavaClass->TYPE_VPN;
    #define TYPE_VPN 0x00000011
    //TJConnectivityManager::JavaClass->TYPE_WIMAX;
    #define TYPE_WIMAX 0x00000006
    
    void __fastcall Tfm_main_wifistatus::Timer1Timer(TObject *Sender)
    {
            UnicodeString net_str;
            _di_JNetworkInfo n_info = f_ConnectivityManager->getActiveNetworkInfo();
            if (n_info != nullptr)
            {
                switch (n_info->getType())
                {
                case TYPE_WIFI:
                    net_str = L"(TYPE_WIFI)";    break;
                case TYPE_MOBILE:
                    net_str = L"(TYPE_MOBILE)";  break;
                case TYPE_VPN:
                    net_str = L"(TYPE_VPN)"; break;
                }
            }
            else
                net_str = L"(nullptr)";
    }
    

    You can get the status of a network interface.


    0 0

    C++Builder 10.2 Tokyo does not have BDE installed.
    So, Install BDE separately in C++Builder 10.2 Tokyo.
    It is after the end of the all of the installation.

     

    Download BDE Installer for RAD Studio, Delphi, C++Builder 10.2 Tokyo

    Download the installer from the URL below.
    ID: 30752, BDE Installer for RAD Studio, Delphi, C++Builder 10.2 Tokyo 

     

    Check the Paradox data.

    Use the sample file named biolife.db.
    This is sample data of Paradox.
    I brought it from C++Builder 5 sample data.

    There is a "Graphic" field in biolife.db. "Graphic" is Blob type.

     

    Save the Blob data in the JPEG format using the BDE.

    In VCL, JPEG can be processed using TJPEGImage.

    #include <Vcl.Imaging.jpeg.hpp>
    

    Use TTable to get all of biolife.db.

    //---------------------------------------------------------------------------
    void __fastcall TfmMain::bde_biofish_save()
    {
        // created a new TTable and set the biolife table.
        std::auto_ptr<TTable> l_table( new TTable(this));
        l_table->DatabaseName    = "DBDEMOS";
        l_table->TableName      = "biolife.db";
        l_table->Active         = true;
        l_table->FindFirst();
        //Loop for acquiring all data.
        while (! l_table->Eof)
        {
            std::tr1::shared_ptr<TJPEGImage> l_jpeg(new TJPEGImage());
            std::tr1::shared_ptr<TMemoryStream> l_ms(new TMemoryStream());
    
            //Using the CreateBlobStream() function will create a new TStream.
            //Instances created with TStream need to be deleted.
            std::tr1::shared_ptr<TStream> ss(l_table->CreateBlobStream(
                l_table->FieldByName("Graphic"), TBlobStreamMode::bmRead));
            ss->Position = 8;
            l_ms->CopyFrom(ss.get(), ss->Size-8);
            l_ms->Position = 0;
            std::tr1::shared_ptr<TBitmap> b(new TBitmap());
            b->LoadFromStream(l_ms.get());
            //Convert calling Bitmap data to jpeg.
            l_jpeg->Assign(b.get());
    
            //When saving JPEG, the file name is "Species No" and "Species Name".
            l_jpeg->SaveToFile(l_table->FieldByName("Species No")->AsString + "_" +
                StringReplace(l_table->FieldByName("Species Name")->AsString, " ", "_", TReplaceFlags() <<rfReplaceAll) +
                ".jpeg");
            //Move to the next record.
            l_table->Next();
        }
    }
    

    Make the file name "Species No" + "Species Name" + ". Jpeg".
    "Species No" + "Species Name" exists in DB field.

     

     

     

    Confirm the output JPEG data


    0 0

    In den letzten Tagen war es hier etwas ruhig..... Konferenzen und Urlaub muss auch mal sein.

    Hier einige Eindrücke von den Forentagen in Hamburg:

    Sebastian Gingter

    Haupt-Session-Raum / Panorama

    Die Vortragenden:

    David Millington, Stefan Glienke, Bernd Ott, Sebastian Gingter, Volker Hillmann, Christina Kruse, Bernd Ua, Ulf Klarmann, Frank Lauter, Bruno Fierens, Uwe Raabe, ....

    Und natürlich von der EKON aus Köln:

    Marco Cantus Keynote

    Bernd Ua Keynote

    Einer meiner Vorträge

    Mit insgesamt weit über 250 Teilnehmern wirklich tolle und erfolgreiche Veranstaltungen.

     


    0 0

    A few weeks ago, I wrote about how RAD Studio 10.2.1 supports debug vizualizers for Delphi generics:

    Debug visualisers are a type of IDE plugin that allows you to change the display of a variable in the various debug windows (Local Variables, Watches, Inspector, and Evaluate/Modify.) For example, the TDateTime visualiser takes the double value that represents time and instead displays that time converted to a string. You register a debug visualiser for a type, so all variables of that type, and optionally descendants of that type, go through your visualiser.

    In previous versions, as with generics, there was no way to register a visualizer for "MyTemplate<T, U>".  The visualizer would never fire because there would be no type in the compiled app named "MyTemplate<T, U>" - it would be a specific instantiation, such as MyTemplate<int, std::string>.

    In 10.2.1, we have introduced support for registering a visualizer for C++ templates.  In fact, it works exactly the same as Delphi: the only trick to be aware of is that sometimes a C++ template has more parameters than you may be aware of.  This is important when implementing the visualizer's GetSupportedType() method which returns the type name.

    For example, you may want to register a visualizer for a vector, and use the typename "std::vector<T>".  When the visualizer is installed, you won't see it have any effect and will realize it's not being called for vectors.  You actually need to return a typename with two generic parameters (the name of each doesn't matter), such as "std::vector<T, Allocator>".  Similarly, a std::map is a template with not only key and value template params, but comparison and allocator params too, so the correct type string is something like "std::map<K, V, Compare, Allocator>" (again, the exact names of the parameters doesn't matter.)

    Unlike visualizers for a normal type, the visualizer is called only for an instantiation of the type with the type string specified, not descendants of the type.  If you need to alter display for descendants of a generic, you will need to register for those descendants too.

    Finally, here is a code snippet demonstrating a template visualizer

    Templates are widely used in C++ and we hope being able to register a visualizer for them will be useful for you!


    0 0

    In RAD Studio 10.2.1 we added support for debug visualizers for Delphi generic and C++ template types.  A debug visualizer is an IDE plugin that allows you to change the display of a variable in the various debug windows, such as Local Variables and Watches.

    "Great!", you may think, "but how do I actually write one of these visualizers?"

    Pretty easily, as it turns out.

    A debug vizualiser is an interfaced class that implements some specific Open Tools API interfaces (see toolsapi.pas), located in a DLL or package, and an instance of which is registered with the IDE when the package is loaded.  Those interfaces are:

    • IOTADebuggerVisualizer, IOTADebuggerVisualizer250: name and description of the visualizer, list of types it's interested in; version 250 adds support for generics or templates by allowing you to specify that a type string is for a generic or template type.
    • IOTADebuggerVisualizerValueReplacer: this lets you replace the result of an expression returned by the debug evaluator with some other content - whatever you want.  You can get more advanced than this, such as showing an external window for the results.  This is just a simple example.
    • IOTAThreadNotifier, IOTAThreadNotifier160: let you handle an evaluation completing.  A notifier, by convention in the ToolsAPI, also always has four other methods to do with saving, destroying and modification that are not meaningful in this example.

    Generic and template debug visualizer example

    Here's a complete visualizer code snippet.  To test this out, create a new package, and add designide to the Requires. Then add a unit called GenericVisualizer.pas to it and paste in the following source code.  To test it out, just right-click and Install, and then it's running right there inside your local IDE instance.  (You can also debug the IDE with IDE if you want to do some more advanced work and load it while debugging an instance of the IDE with your first copy of the IDE.)

    Source code

    .
    unit GenericVisualizer;
    
    interface
    
    procedure Register;
    
    implementation
    
    uses
      Classes, SysUtils, ToolsAPI;
    
    type
      TGenericVisualizer = class(TInterfacedObject, IOTADebuggerVisualizer,
        IOTADebuggerVisualizer250, IOTADebuggerVisualizerValueReplacer,
        IOTAThreadNotifier, IOTAThreadNotifier160)
      private
        FCompleted: Boolean;
        FDeferredResult: string;
      public
        { IOTADebuggerVisualizer }
        function GetSupportedTypeCount: Integer;
        procedure GetSupportedType(Index: Integer; var TypeName: string;
          var AllDescendants: Boolean); overload;
        function GetVisualizerIdentifier: string;
        function GetVisualizerName: string;
        function GetVisualizerDescription: string;
        { IOTADebuggerVisualizer250 }
        procedure GetSupportedType(Index: Integer; var TypeName: string;
          var AllDescendants: Boolean; var IsGeneric: Boolean); overload;
        { IOTADebuggerVisualizerValueReplacer }
        function GetReplacementValue(const Expression, TypeName,
          EvalResult: string): string;
        { IOTAThreadNotifier }
        procedure EvaluateComplete(const ExprStr: string; const ResultStr: string;
          CanModify: Boolean; ResultAddress: Cardinal; ResultSize: Cardinal;
          ReturnCode: Integer);
        procedure ModifyComplete(const ExprStr: string; const ResultStr: string;
          ReturnCode: Integer);
        procedure ThreadNotify(Reason: TOTANotifyReason);
        procedure AfterSave;
        procedure BeforeSave;
        procedure Destroyed;
        procedure Modified;
        { IOTAThreadNotifier160 }
        procedure EvaluateComplete(const ExprStr: string; const ResultStr: string;
          CanModify: Boolean; ResultAddress: TOTAAddress; ResultSize: LongWord;
          ReturnCode: Integer);
      end;
    
    type
      TGenericVisualierType = record
        TypeName: string;
        IsGeneric: Boolean;
      end;
    
    const
      GenericVisualizerTypes: array [0 .. 4] of TGenericVisualierType = (
        (TypeName: 'MyGenericType.IGenericInterface<T,T2>'; IsGeneric: True),
        (TypeName: 'MyGenericType.TGenericClass<System.Integer>'; IsGeneric: False),
        (TypeName: 'MyGenericType.TGenericClass<T>'; IsGeneric: True),
        (TypeName: 'std::vector<T, Allocator>'; IsGeneric: True),
        (TypeName: 'std::map<K, V, Compare, Allocator>'; IsGeneric: True)
      );
    
      { TGenericVisualizer }
    
    procedure TGenericVisualizer.AfterSave;
    begin
      // don't care about this notification
    end;
    
    procedure TGenericVisualizer.BeforeSave;
    begin
      // don't care about this notification
    end;
    
    procedure TGenericVisualizer.Destroyed;
    begin
      // don't care about this notification
    end;
    
    procedure TGenericVisualizer.Modified;
    begin
      // don't care about this notification
    end;
    
    procedure TGenericVisualizer.ModifyComplete(const ExprStr, ResultStr: string;
      ReturnCode: Integer);
    begin
      // don't care about this notification
    end;
    
    procedure TGenericVisualizer.EvaluateComplete(const ExprStr, ResultStr: string;
      CanModify: Boolean; ResultAddress, ResultSize: Cardinal; ReturnCode: Integer);
    begin
      EvaluateComplete(ExprStr, ResultStr, CanModify, TOTAAddress(ResultAddress),
        LongWord(ResultSize), ReturnCode);
    end;
    
    procedure TGenericVisualizer.EvaluateComplete(const ExprStr, ResultStr: string;
      CanModify: Boolean; ResultAddress: TOTAAddress; ResultSize: LongWord;
      ReturnCode: Integer);
    begin
      FCompleted := True;
      if ReturnCode = 0 then
        FDeferredResult := ResultStr;
    end;
    
    procedure TGenericVisualizer.ThreadNotify(Reason: TOTANotifyReason);
    begin
      // don't care about this notification
    end;
    
    function TGenericVisualizer.GetReplacementValue(const Expression, TypeName,
      EvalResult: string): string;
    begin
      Result := 'Generic visualizer:' + '; ' +
        'Expression: ' + Expression + '; ' +
        'Type name: ' + TypeName + '; ' +
        'Evaluation: ' + EvalResult;
    end;
    
    function TGenericVisualizer.GetSupportedTypeCount: Integer;
    begin
      Result := Length(GenericVisualizerTypes);
    end;
    
    procedure TGenericVisualizer.GetSupportedType(Index: Integer;
      var TypeName: string; var AllDescendants: Boolean);
    begin
      AllDescendants := True;
      TypeName := GenericVisualizerTypes[index].TypeName;
    end;
    
    procedure TGenericVisualizer.GetSupportedType(Index: Integer;
      var TypeName: string; var AllDescendants: Boolean; var IsGeneric: Boolean);
    begin
      AllDescendants := True;
      TypeName := GenericVisualizerTypes[index].TypeName;
      IsGeneric := GenericVisualizerTypes[index].IsGeneric;
    end;
    
    function TGenericVisualizer.GetVisualizerDescription: string;
    begin
      Result := 'Sample on how to register a generic visualizer';
    end;
    
    function TGenericVisualizer.GetVisualizerIdentifier: string;
    begin
      Result := ClassName;
    end;
    
    function TGenericVisualizer.GetVisualizerName: string;
    begin
      Result := 'Sample Generic Visualizer';
    end;
    
    var
      GenericVis: IOTADebuggerVisualizer;
    
    procedure Register;
    begin
      GenericVis := TGenericVisualizer.Create;
      (BorlandIDEServices as IOTADebuggerServices).RegisterDebugVisualizer(GenericVis);
    end;
    
    procedure RemoveVisualizer;
    var
      DebuggerServices: IOTADebuggerServices;
    begin
      if Supports(BorlandIDEServices, IOTADebuggerServices, DebuggerServices) then
      begin
        DebuggerServices.UnregisterDebugVisualizer(GenericVis);
        GenericVis := nil;
      end;
    end;
    
    initialization
    
    finalization
      RemoveVisualizer;
    
    end.

     

    To test

    For Delphi

    Define some types:

    .
    type
      IGenericInterface<T,T2> = interface
      ['{2395EEA7-7E2E-485E-B6D3-C424A12FAE7F}']
      end;
    
      TGenericClassFromInterface<T,T2> = class(TInterfacedObject, IGenericInterface<T,T2>)
      end;
    
    
      TGenericClass<T> = class(TObject)
      end;
    
      TGenericClassDescendant<T> = class(TGenericClass<T>)
      end;
    
      TGenericClassDescendantInt = class(TGenericClass<Integer>)
      end;

    This example is longer than the C++ one, because it demonstrates both generic classes and interfaces.  It also shows some descendant types, where you need to register the descendant type separately. (For a non-generic-type debug visualizer, the visualizer is called for descendants of the registered type automatically.)

    And create a new console app, giving it the contents:

    .
    procedure foo;
    var
      a: TGenericClassFromInterface<Integer, string>;
      a1: IGenericInterface<Integer, string>;
      b: TGenericClass<string>;
      c: TGenericClass<Integer>;
      d: TGenericClassDescendant<string>;
      e: TGenericClassDescendantInt;
    begin
      a := TGenericClassFromInterface<Integer, string>.Create;
      a1 := a;
    
      b := TGenericClass<string>.Create;
      c := TGenericClass<Integer>.Create;
      d := TGenericClassDescendant<string>.Create;
      e := TGenericClassDescendantInt.Create;
    
      writeln('abc'); // set breakpoint here
    end;
    
    begin
      try
        foo;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.

    For C++

    Create a new console app (and some shiny new template types as well, if you wish) and give it the contents:

    .
    int _tmain(int argc, _TCHAR* argv[])
    {
    	std::vector<int> myVec;
    	std::map<int, std::string> myMap;
    
    
    	return 0;    // BP here
    }

    To extend

    This is the exciting bit!  Try changing the data returned from GetReplacementValue(), and also try evaluating expressions yourself in the visualizer to use in the returned replacement.

    Have fun!

     


    0 0
  • 11/29/17--04:46: iPhone X, Face ID und Delphi
  • Apple bietet für das iPhone X eine neue Autorisierungsmöglichkeit an: Face ID. Generell ist Face ID, als Nachfolger von Touch ID (dem Fingerabdrucksensor seit dem iPhone 5S) auf API Ebene kompatibel zu Touch ID. Also sollte die kleine Unit von https://bitbucket.org/allesbeste/ios-touchid-wrapper-for-delphi auch hier mit Face ID funktionieren.

    Und die Unit funktioniert auch mit Delphi und Face ID auf dem iPhone X:

    Generell kapselt die Unit iOSapi.LocalAuthentication (vom oben angegeben Link) die absoluten, aber ausreichenden Grundfunktionalitäten aus dem LocalAuthetication-Framework: Die Fallback-Methode habe ich etwas umgeschrieben. Hier wird die Statusbar (ein anderes Thema für iPhone X) einfach rot oder grün gefärbt:

    uses
    [...] iOSapi.LocalAuthentication [...]


    procedure TFormIrgendwas.TouchIDReply(success, error: Pointer); var bSuccess: Boolean; begin bSuccess := false; if not Assigned(error) AND Assigned(success) then begin bSuccess := ((Integer(success)) = 1); end; if bSuccess then begin // hat geklappt! Autorisiert self.SystemStatusBar.BackgroundColor := TAlphaColorRec.Darkgreen; end else begin // keine Autorisierung! self.SystemStatusBar.BackgroundColor := TAlphaColorRec.Darkred; end; // Form neu zeichnen self.Invalidate; end;

    0 0

    In den letzten Tagen bekomme ich häufiger diese Frage:

    Frage: Ich möchte den Lizenzserver ELC unter Windows Server 2016 installieren. Aber schon während der Installation bekomme ich einen hässlichen Fehler. Ich benutze dazu die Installationsdatei von http://altd.embarcadero.com/download/ELC/win64/ELC532_64.exe, wie hier beschrieben:
    http://docwiki.embarcadero.com/ELC/53/en/ELC_Quick_Start

    Antwort: Nutzen Sie bitte diese Installationsdatei

    http://altd.embarcadero.com/download/ELC/win64/ELC531_64.exe

    Die geht


    0 0

    I am excited to announce that RAD Studio 10.2.2 was released today. 10.2 Tokyo, Release 2 (also known as 10.2.2) is an update of Delphi 10.2 Tokyo, C++Builder 10.2 Tokyo and RAD Studio 10.2 Tokyo available for any active Update Subscription customer.

     

    10.2.2 Registered User Download Links:

    Docwiki: http://docwiki.embarcadero.com/RADStudio/Tokyo/en/10.2_Tokyo_-_Release_2  

     

    Several key new features were added, including FireMonkey Quick Edit support, a number of new VCL controls, a new dark themed IDE option, a RAD Server single site deployment license in Enterprise and Architect editions, installer and welcome page enhancements and more.

     

    Also included is newly added support for macOS High Sierra, and enhanced platform support for iOS 11 (including iPhone X), Android 8, Windows 10, and Linux, additional enhancements throughout various product areas, and over quality improvements to over 150 publicly reported issues.

     

     

    Key RAD Studio 10.2.2 Features:

    The new dark theme is designed for night-time work or lengthy use, with updated component icons that complement both the light and dark theme. Easily toggle between the newly added dark theme and the existing light theme through a newly provided option on the desktop toolbar in the IDE.

     

     

    Improve developer productivity with the new Quick Edit feature for FireMonkey, allowing you to quickly perform common actions in the FireMonkey Form Designer.

     

     

     

    Also new in 10.2.2 are four new VCL Windows GUI controls, designed with Windows 10 in mind.

    • TCardPanel: The new Card Panel is a specialized component that manages a collection of cards.
    • TStackPanel: The Stack Panel is a new container control that allows you to automatically align all parented controls vertically or horizontally while retaining each control's custom height and width settings.
    • TDatePicker and TTimePicker are modern date and time picker controls with support for multiple formatting options, a custom drop-down count and ok and cancel date and time selection buttons.

     

     

    Also new is an updated IDE Welcome Page with new sample projects, videos from our YouTube channel, and a calendar of local and global events to help new users get started quickly.

     

    Delphi, C++Builder and RAD Studio Enterprise and Architect editions now include a RAD Server Single Site/Single Server deployment license. Also covered by the included single site RAD Server license is BeaconFence deployment for a single location with unlimited users, and no square footage limitation

     

    We've also enhanced our JavaScript client support for Sencha Ext JS with RAD Server through TDataSet JSON mapping.

     

    Click on our new 10.2.2 product video below to see the key new features in action:


    [YoutubeButton url='https://www.youtube.com/watch?v=iGnJANX18uw']

     

    New to RAD Studio? Download the RAD Studio 10.2.2 Trial today!


    0 0

    In den letzten Tagen habe ich einige Webinare durchgeführt. Selbstverständlich gibt es davon Aufzeichnungen auf dem Embarcadero Germany Channel auf YouTube.

    • Delphi als Lehr und Lernsprache

      [YoutubeButton url='https://www.youtube.com/watch?v=fmRPL9LVJOk']
    • Delphi 10.2 Release 2 Neuerungen

      [YoutubeButton url='https://www.youtube.com/watch?v=PUfZ_Vv3-s0']
    • Delphi und Linux Entwicklung
      Grundlagen

      [YoutubeButton url='https://www.youtube.com/watch?v=NMfdzzt9YWY']

      FMX Linux

      [YoutubeButton url='https://www.youtube.com/watch?v=5ZN5CGp-dCU']

    0 0

    Frage: Ich kann mit dem RAD Studio/Delphi/C++Builder  10.2 auf meinem Android 8.0 Gerät nicht debuggen. Wodran liegt das?

    Antwort: Google ist mit dem Android 8.0 Release "etwas" über das Ziel hinausgeschossen..... Google hat mit dem Release von Android 8.0 in diesem Sommer (war das ein Sommer?) einige Sicherheitsfeatures nachgeschärft. Leider ist dadurch das Debugging flöten gegangen. "Can't open socket: Permission denied.".

    Dazu gibt es auch einige Diskussionen hier und hier.

    Die gute Nachricht: Google hat das mit Android 8.1 geradegebogen. Viel Glück an die Android-User ein Oreo 8.1 Update zu erhalten.

    Quelle: http://blog.marcocantu.com/blog/2017-december-delphi-android81-debugging.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+marcocantublog+%28marcocantu.blog%29

     


    0 0

    New in 10.2.2 TFDBatchMoveJSONWriter was added.

    TFDBatchMoveJSONWriter is a Writer that combines with TFDBatchMove to out to a simple JSON. But,  TFDBatchMoveJSONWriter has the function of generating Model definition of Ext JS.
    I tried with a field dynamically created with TFDMemTable.

    code

    The code below is a simple 64-bit console application.
    I wrote this code using C++Builder.

    umain.cpp
    #include <vcl.h>
    #include <windows.h>
    
    #pragma hdrstop
    #pragma argsused
    #pragma link "dbrtl.a"
    #pragma link "FireDAC.a"
    #pragma link "FireDACCommonDriver.a"
    #pragma link "FireDACCommon.a"
    
    #include <tchar.h>
    #include <iostream>
    #include <System.JSON.hpp>
    #include <FireDAC.Stan.Intf.hpp>
    #include <FireDAC.Stan.Option.hpp>
    #include <FireDAC.Stan.Param.hpp>
    #include <FireDAC.Stan.Error.hpp>
    #include <FireDAC.DatS.hpp>
    #include <FireDAC.Phys.Intf.hpp>
    #include <FireDAC.DApt.Intf.hpp>
    #include <FireDAC.Comp.BatchMove.JSON.hpp>
    #include <FireDAC.Comp.BatchMove.hpp>
    #include <FireDAC.Comp.BatchMove.DataSet.hpp>
    #include <Data.DB.hpp>
    #include <FireDAC.Comp.DataSet.hpp>
    #include <FireDAC.Comp.Client.hpp>
    #include <FireDAC.Stan.StorageJSON.hpp>
    #include <functional>
    #include <string>
    #include <sstream>
    
    struct dbs
    {
        TFDMemTable* f_MemTable1;
        TFDBatchMove* f_BatchMove1;
        TFDBatchMoveDataSetReader* f_DataSetReader1;
        TFDBatchMoveJSONWriter* f_JSONWriter1;
        TFDStanStorageJSONLink* f_JSONLink1;
        dbs(std::function<void(TFDMemTable*)> func)
        {
            f_MemTable1         = new TFDMemTable(nullptr);
            f_BatchMove1        = new TFDBatchMove(nullptr);
            f_DataSetReader1    = new TFDBatchMoveDataSetReader(nullptr);
            f_JSONWriter1       = new TFDBatchMoveJSONWriter(nullptr);
            f_JSONLink1         = new TFDStanStorageJSONLink(nullptr);
            f_DataSetReader1->DataSet   = f_MemTable1;
            f_BatchMove1->Reader        = *f_DataSetReader1;
            f_BatchMove1->Writer        = *f_JSONWriter1;
            func(f_MemTable1);
        };
        static inline String IToString(int iin)
        {
            std::wostringstream ss;
            ss << iin;
            return ss.str().c_str();
        }
    
        ~dbs()
        {
            delete f_MemTable1;
            delete f_BatchMove1;
            delete f_DataSetReader1;
            delete f_JSONWriter1;
            delete f_JSONLink1;
        };
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        try
        {
            TStringList* alist = new TStringList();
            try
            {
                dbs adbs([](TFDMemTable* memt)
                    {
                        //Field definition of TFDMemTable* instance.
                        //Create five fields.
                        for (int i = 0; i < 5; i++)
                        {
                            TStringField* aField    = new TStringField(nullptr);
                            aField->FieldName       = "Column" + dbs::IToString(i);
                            aField->Size            = 50;
                            memt->Fields->Add(aField);
                        }
                    });
                //Then execute the GenerateExtJSModel() method.
                //This GenerateExtJSModel() is a TFDBatchMoveJSONWriter class that has been added than 10.2.2.
                adbs.f_JSONWriter1->GenerateExtJSModel("Table1", true, alist);
                //Console out.
                std::wcout << alist->Text.c_str() << std::endl;
            }
            __finally
            {
                delete alist;
            }
    
        }
        catch(...)
        {
    
        }
        return 0;
    }
    

    result GenerateExtJSModel()

    The output store definition is as follows.

    Ext.define('Table1', {
      extend: 'Ext.data.Model',
      requires: [
        'Ext.data.field.Field'
      ],
      fields: [
        { name: 'Column0', type: 'string' },
        { name: 'Column1', type: 'string' },
        { name: 'Column2', type: 'string' },
        { name: 'Column3', type: 'string' },
        { name: 'Column4', type: 'string' }
      ]
    });
    

    It can be output in Ext JS store definition.
    2018-01-011450.png


    0 0

    あけましておめでとうございます。2018年が皆様にとって、飛躍の年であるよう祈っております。新しい年の始まりにあたり、Eショップ各社にて、新春初売りキャンペーンを実施します。幅広い製品ラインナップが18% OFF!1月31日までの期間限定です。この機会をぜひご活用ください。

     

    C++Builder 10.2 Release 2 TCardPanelについて

    TCardPanel概要

    TCardPanelは、複数のTCardとセットで利用します。
    IDEのデザイナ上でTCardを作成し管理する事ができ、TCardPanelを配置した上にTButtonなどのコンポーネントをドラッグ&ドロップすると自動でTCardが作られその配下にTButtonが配置されます。
    TCardはフォーム上に作られるが、TCardPanel内部ではTList<TCard>を作って管理している。


    TCardPanel機能

    TCardを管理する為のいくつかの機能があります。

    CreateNewCard();

    新しくTCardを作成し、アクティブにする。

     TCard* acard = CardPanel1->CreateNewCard();
        TButton* b1 = new TButton(this);
        b1->Parent =  acard;

     

    DeleteCard(int Index);

    TCardを削除する。コンテナから消すだけではなくインスタンスもdeleteする。

     //アクティブなカード番号を取得しカードを削除
        CardPanel1->DeleteCard(CardPanel1->ActiveCardIndex);

     

    FindNextCard(int Index, bool GoForward, bool CheckCardVisible);

    順方向または逆方向に順番に次のカードのインデックスを取得する。

    引数名 内容
    Index 開始位置
    GoForward false =前, true=後
    CheckCardVisible false = visibleカードだけを検索
     int i = CardPanel1->FindNextCard(0,true,false);

     

    NextCard();

    次のカードに移動

     CardPanel1->NextCard();

     

    PreviousCard();

    前のカードに移動

     CardPanel1->PreviousCard();

     

    プロパティ ActiveCardIndex

    アクティブなカード番号を取得

     int i = CardPanel1->ActiveCardIndex;

     

    プロパティ ActiveCard

    アクティブなカード取得

     TCard* acard = CardPanel1->ActiveCard;

     

    プロパティ CardCount

    TCardPanel上のカード数

     int acount = CardPanel1->CardCount;

     

    プロパティ Cards[int Index]

    TCardPanel上カード個別取得

     TCard* acard = CardPanel1->Cards[0];

     

    プロパティ Loop

    ナビゲートするときにNextCardおよびPreviousCardのメソッドがカードリストの反対側にループするかどうかを制御します。

     CardPanel1->Loop = true;

     

    イベント OnCardChange

    アクティブなカードが別のカードに変更された場合に発生します。

    typedef void __fastcall (__closure *TCardChangeEvent)(System::TObject* Sender, TCard* PrevCard, TCard* NextCard);

     


older | 1 | .... | 6 | 7 | (Page 8) | 9 | 10 | newer