• Recommendations for creating user interfaces in Delphi. Abstract: Using open interfaces of the Delphi programming environment Programs to manage your business

    Creation interface the user is reduced to selecting from the palette of components the Delphi components necessary for the program to work, serving interface management, as well as interface displaying information, and transferring it to the Form with subsequent layout.

    The user interface you create should use standard elements familiar to users and provide maximum convenience. All this is ultimately determined by such a criterion as the effectiveness of the interface - maximum results with minimal effort.
    The principles of creating a user-friendly interface are known. Three main principles can be considered as the most general principles when creating user interfaces:

    1. The program should help complete a task, and not become that task.
    2. When working with the program, the user should not feel like a fool.
    3. The program should work in such a way that the user does not consider the computer a fool.
    First principle- this is the so-called “transparency” of the interface. The user interface should be intuitive, easy to learn, and not create problems for the user that he will have to overcome during the work process. Use standard components without unnecessary embellishment, use familiar control techniques used by similar programs, and you will achieve the performance criteria first principle.

    Second principle is to neglect the intellectual abilities of users. From my own experience, I know that often users not only do not know how to work on a computer, but are simply afraid to do anything on their own. Therefore, the user interface should be as friendly as possible.
    Moreover, users’ fears are often justified, because the cost of the program, and even the computer itself, cannot be compared with the cost, for example, of a database created over many years of effort. That is why, when creating a user interface, a programmer must always build “foolproof protection” into the program - against incorrect actions and user input of incorrect data. But some programmers get too carried away with such protection, make it too intrusive, and as a result the program’s operation resembles the famous “one step to the left, a step to the right is considered an escape”! And what the programmer creates as a solution to a problem begins to create problems itself.
    To comply second principle there is no need to allow the program to “correct” the user’s actions and indicate exactly how he should act, forcing him into a narrow framework. Also, you should not get too carried away with displaying informational prompt messages, especially dialog ones, as this distracts the user from work. It would be better to provide the ability to disable hints altogether.

    Third principle is to create a program with the highest possible "mental" capabilities. Despite the rapid development of computer technology, even widely used programs can only very conditionally be called having artificial intelligence. They interfere with the user's work by displaying dialog boxes with stupid questions that cause confusion even in the simplest situations. As a result, users exclaim in their hearts: “What a stupid machine!”
    I personally am irritated by the constant questions from almost all text editors about whether to save the changed text, although the original and current text do not differ by a single character. Yes, I typed something, but then I returned everything back, is it really impossible to figure it out! I have to check if I haven't ruined anything after all.

    Try to adhere to the following rules:

    Standard interface elements
    Use components that are standard for this interface element. Having encountered your program, the user will not waste time getting to know each other, but will immediately start working - this is one of the signs of a professionally made program.
    Small palette of tools
    Try not to use too many different components. And naturally, having used one standard component somewhere in one place, in a similar case also use it.
    Equal spacing between controls
    Place interface elements at the same distance from each other. Components scattered haphazardly create the feeling of an unprofessionally made product. And vice versa, carefully verified placement of buttons, switches, checkboxes and other components that make up the interface on the Form is a sign of high-quality work.
    TabOrder. "Correct" order
    TabOrder is the order in which the screen cursor moves across controls when a key is pressed Tab. In a correctly written program, the cursor moves following the logic of the user's work with the program. When creating a program, the programmer often changes components, removes some, and adds others as needed. As a result, in the finished program the cursor jumps chaotically around the Form. After completing the program, do not forget to configure TabOrder.
    Font selection
    Just leave the fonts alone. Delphi's default fonts are suitable for any system on which your program may run. Use bold font only to highlight important elements. Application italics and especially underlining, which the user might mistake for a hyperlink is bad form.
    Choice of colors
    As for the colors of interface elements, just as in the case of fonts, it is better to leave them standard, by default. Delphi uses the Windows system palette, and the user can easily customize the colors by changing it.
    Alternative management
    A professionally made program should be able to be controlled not only with the mouse, but also with the keyboard. There should be no functions that can only be performed with the mouse (drawing in graphic editors does not count!). For the most used functions, you should provide “hot keys” for quick access.
    Interface bricks
    As for specific elements of the user interface, the quality of user interaction with the program depends on:
    • compliance of the control element with the task it performs;
    • rules by which the control element operates.
      This page discusses the rules for creating some interface elements.
    And now I want to show what tools Delphi offers for managing components on the Form, their relative position and cursor behavior when a key is pressed Tab.

    To arrange the components relative to each other in the correct order, first it is necessary to highlight them. You can simply circle the area on the Form that contains the selected components. Or by holding " Shift", use the same mouse to indicate each component to be selected. Click the mouse again on the selected component (while pressing " Shift") deselects it.

    The selected components can be managed as a single whole - moved around the Form, assigned values ​​to the same properties, copied (for installation, for example, on another Form), even deleted.

    Now right-click on one of the components and select from the pop-up menu Position -> Align... A dialog box will appear allowing you to adjust the horizontal and vertical position of the components in the group. For example, we need to align our four buttons to the left and make sure there is equal vertical distance between them. To do this, select the radio buttons Horizontal: Left sides And Vertical: Space equally.

    Selecting the item Center, we will arrange the components so that their centers will be located on the same line horizontally or vertically, and the item Center in window moves components to the center of the window, also horizontally or vertically.

    In the same menu line Tab O rder... causes a dialog box to appear that controls how the cursor moves through interface elements when a key is pressed Tab. When the Form appears on the screen, the cursor will naturally be on the component located on the first line of the dialog box. And then it will move down the list. In the dialog box, two blue up and down arrows control the position of the selected component. Select the required component, use the arrows to move it to the desired line in the list, and so on.

    When selecting a menu item Control -> A submenu appears consisting of two items:

    • Bring to Front
    • Send to Back
    These are component methods that are also available programmatically. Button1.SendToBack moves the button to the "background" and Button1.BringToFront- to the “foreground”. That is, if one component is positioned above another, these methods swap their positions. The cases in which this might apply are pretty obvious.

    only for the result

    strict adherence to deadlines

    Transparency

    project implementation

    technical support as a gift

    Programming, modifications, consultations on 1C

    How we work

    1. We discuss the problem over the phone. If you have remote access, display it on your computer screen.

    2. We estimate the work in rubles if the project is large; if not, the approximate number of hours.

    3. We get the job done.

    4. You accept the work in your program; if there are any shortcomings, we correct them.

    5. We issue an invoice, you pay.

    Cost of work

    1. All work is divided into 3 categories: consultation, updating a standard configuration, developing or programming a new report, processing, button, etc.

    3. For work longer than 10 hours, a technical specification with a description and cost of the work must be prepared in advance. Work begins after the technical specifications have been agreed upon with you.

    Technical support

    1. If you find any errors in previously accepted work within 3 months, we correct them free of charge.

    2. For regular customers, we correct any shortcomings in our work free of charge within a year.

    Software to manage your business.

    Buy 1C:Enterprise

    We are an official dealer of 1C, you can purchase various software products and licenses from us. In addition to purchasing the “box,” we will help you set up the program, provide advice and make basic settings.

    • Accounting
    • Store automation
    • Wholesale sales
    • Installation and initial setup assistance is included in the package!
    • Fine-tuning configurations to suit customer needs, developing new modules in the absence of the necessary functions in the standard configuration.
    1C:Accounting 1C: Trade Management 1C: Retail 1C: Salary and Personnel Management
    From 3300 rub. From 6700 rub. From 3300 rub. From 7400 rub.

    Server provision.

    Instant setup of server + 1C.

    No server? No problem, we’ll select and quickly set up a server in the cloud. For a small fee you get a very reliable solution.

    • Availability 24\7
    • There is no need to have your own system administrator (the savings will cover the cost of your server).
    • Quick setup and installation of 1C on the server, in 3 days you will already have a fully working system.
    • You can move to a local server at any time if you are not satisfied with the solution.

    SMS from your 1C

    Do you want your customers to find out about promotions and discounts? Are clients not returning? Set up sending SMS directly from 1C!

    Our company will be able to quickly set up sending SMS to your customers directly from 1C. Examples of events that can be automated:

    • Thanks for the purchase and bonuses are awarded immediately after the next purchase.
    • Accrual of bonuses to the card as a gift for a birthday\other significant or holiday.
    • Notification of goods arrival at the warehouse.
    • Expiration of gift bonuses.
    • Notification of receipt of advance payment and reservation of goods.
    • Address with directions to the store/office, telephone numbers.
    • Etc.

    Setting up in 1C can be done by our specialists or your employees. You can view the tariffs on the SMS tariffs page.

    • Guaranteed SMS delivery, money is charged only for delivered SMS.
    • Separate pricing for each SMS.
    • Top up your balance in different ways.
    • View the history of all sent SMS at any time.
    • The sender's name instead of the digital number in the message recipient's phone.

    I have a problem using a Delphi class from C++ code. delphi dll demo, which exports a function that returns an object.
    my Delphi Dll code looks like this:

    Library DelphiTest; // uses part.... type IMyObject = interface procedure DoThis(n: Integer); function DoThat: PWideChar; end; TMyObject = class(TInterfacedObject,IMyObject) procedure DoThis(n: Integer); function DoThat: PChar; end; // TMyObject implementation go here ... procedure TMyObject.DoThis(n: Integer); begin showmessage("you are calling the DoThis methode with "+intToStr(n) +"parameter"); end; function TMyObject.DoThat: PChar; begin showmessage("you are calling the DoThat function"); Result:= Pchar("Hello im Dothat"); end;

    // export DLL function:

    Function CreateMyObject: IMyObject; stdcall;export; var txt: TextFile; begin AssignFile(txt,"C:\log.log"); Reset(txt); Writeln(txt,"hello"); Result:= TMyObject.Create; end; exports CreateMyObject;

    in my C++ project I declared the IMyObject interface like this:

    Class IMyObject ( public: IMyObject(); virtual ~IMyObject(); virtual void DoThis(int n) = 0; virtual char* DoThat() = 0; );

    and my main function is like this:

    Typedef IMyObject* (__stdcall *CreateFn)(); int main() ( HMODULE hLib; hLib = LoadLibrary(L"DelphiTest.dll"); assert(hLib != NULL); // pass !! CreateFn pfnCreate; pfnCreate = (CreateFn)GetProcAddress((HINSTANCE)hLib, "CreateMyObject "); if (pfnCreate == NULL) ( DWORD errc = GetLastError(); printf("%u\n", errc); // it gets error 127 ) else( printf("success load\n"); ) IMyObject* objptr = pfnCreate(); objptr->DoThis(5); int_s("%i", &in);

    in this example I got a runtime error when I try to access the exported function. errors in the line:
    IMyObject* objptr = pfnCreate();

    Can you tell me what's wrong with my example.
    and if possible, any working example for accessing a Delphi class (in a DLL) from C++ code.

    Solution

    The first problem is calling the method convention. The Delphi interface uses register which is a Delphi specific calling convention. use of stdcall For example, for interface methods.

    The next problem is in C++. Your C++ interface must derive from IUnknown. Additionally, it must not declare a constructor or destructor.

    Apart from this, your Delphi code is exported by PWideChar which is not mapped to char* . It is mapped to wchar_t* .

    Looking further, returning PChar works fine here because your implementation returns a literal. But more serious code will probably want to use a dynamically allocated string, at which point your design is flawed.

    Please note that to create a file in the root of the system drive, you must be an elevated administrator. So this is another potential point of failure.

    I expect there are other bugs, but this is all I've found so far.

    This is an article based on questions on the forums: “How can I return a string from a DLL?”, “How to pass and return an array of records?”, “How to pass a form to a DLL?”.

    So that you don’t spend half your life figuring it out, in this article I will bring everything on a platter.

    The topics of this article have been touched upon more than once in this blog to varying degrees, but in this article they are collected together and justified. In short, you can throw a link to this article at those who develop DLLs.

    Important Note: article must be read sequentially. Code examples are provided only as examples, at each step (point) of the article, the example code is added with new details. For example, at the very beginning of the article there is no error handling; “classical” methods are indicated (such as using GetLastError , the sdtcall convention, etc.), which are replaced with more adequate ones as the article progresses. This was done so that “new” (“unusual”) designs would not raise questions. Otherwise, it would be necessary to insert a note for each example like: “this is discussed in that paragraph below, and this is discussed in this paragraph.” In any case, at the end of the article there is a link to ready-made code, written taking into account everything said in the article. You can just take it and use it. And the article explains why and why. If you are not interested in “why and why”, scroll to the end to the conclusion and the link to download the example.

    Object-oriented programming (OOP), in addition to the concept of a class, also provides for the fundamental concept of an interface.

    What is an interface and what are the features of working with it in the Delphi programming language?

    Interface is a semantic and syntactic construct in program code used to specify the services provided by a class or component (Wikipedia).

    Essentially, an interface defines a list of properties and methods that must be used when working with the class that this interface implements, as well as their signature (name, data type, accepted parameters (for procedures and functions), etc.). Thus, a class that implements a particular interface must implement all its components. Moreover, in strict accordance with how they are described in it.

    Interfaces are often compared to abstract classes, but despite all the similarities, this comparison is not entirely correct. At a minimum, abstract classes allow you to control the visibility of members. At the same time, scopes are not defined for interfaces.

    Interfaces allow you to make the architecture more flexible, as they unify access to this or that functionality, and also allow you to avoid a number of problems associated with class inheritance (interfaces can also be inherited from one another).

    To declare an interface in Delphi, use the interface keyword. This is the same keyword that defines the section of the module that can be accessed from outside (between the interface and implementation keywords). However, when declaring an interface, a different syntax is used, similar to declaring classes.

    Delphi/Pascal

    IMyNewInterface = interface procedure InterfaceProc; end;

    IMyNewInterface =interface

    procedure InterfaceProc ;

    end ;

    Thus, the interface declaration syntax itself is not fundamentally different from other programming languages ​​(the features of the syntax based on Pascal do not count). At the same time, the implementation of interfaces has a number of characteristic features.

    The fact is that Delphi interfaces were originally introduced to support COM technology. Therefore, the IInterface interface, which in Delphi is the ancestor for all other interfaces (a kind of analogue of TObject), already contains three basic methods for working with this technology: QueryInterface, _AddRef, _Release. As a result, if a class implements any interface, then it must also implement these methods. Even if this class is not intended for COM work.

    Due to this feature of the IInterface interface, in Delphi the use of interfaces, in most cases, leads to the addition of obviously unused capabilities to the class.

    There is a library class TInterfaceObject that already contains the implementation of these methods and, when inheriting from it, there is no need to implement them yourself. But since Delphi does not support multiple class inheritance, its use often only causes additional difficulties in the design and implementation of already required functionality.

    All this led to the fact that, despite all the possibilities provided by the interfaces, their practical use in Delphi almost did not go beyond working with COM.

    Being optimized to work mainly with this technology, the interfaces, or rather the functionality and architectural restrictions they necessarily add, do not justify themselves when solving other problems.

    Therefore, many Delphi programmers are still, in fact, deprived of a powerful and flexible tool for developing application architecture.