Windows programming tutorials for FPC

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Bo Berglund
On Sun, 4 Nov 2018 11:29:23 -0500, "James"
<[hidden email]> wrote:

>The Lazarus version is mostly working in Lazarus, but instead of everything
>happening before the form is loaded, is there a way I could make the form
>first, then just start processing everything, so that my messages I send to
> memo1 show up as it's processing?  I'm guessing I need to move my program
>from On-create to somewhere else so it runs after the memo box is showing...
>but I don't know where I would move it to.  
>Any suggestions?
>

In a Lazarus GUI program you can use a timer to handle this.
Just set it to say 1s delay and thenb enable it in Form.OnCreate:

TfrmMain = class(TForm)
 ...
 Timer1: TTimer;
 ...

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  Timer1.Interval := 500; //Default is 1000 ms
  Timer1.Enabled := true;
end;

procedure TfrmMain.Timer1Timer(Sender: TObject);
begin
  //Put your code here
  Application.Terminate; //The application will disappear from view...
end;

If you want your form to be responsive you also need this inside loops
in your program:
Application.ProcessMessages;

Otherwise the form will feel like a dead brick while the Timer
function runs...


--
Bo Berglund
Developer in Sweden

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Luca Olivetti-2
In reply to this post by Zaaphod
El 4/11/18 a les 17:29, James ha escrit:
> I used System.Assign and now I have my program working in Lazarus,  I am exploring both options of making it a real windows application with Lazarus and a console program that can launch save-as.
>
> The Lazarus version is mostly working in Lazarus, but instead of everything happening before the form is loaded, is there a way I could make the form first, then just start processing everything, so that my messages I send to memo1 show up as it's processing?  I'm guessing I need to move my program from On-create to somewhere else so it runs after the memo box is showing... but I don't know where I would move it to.  Any suggestions?

Oh, I thought you just wanted the program to work as a normal console
(silent) application and just show the form in case of errors.

Try this: instead of OnCreate use Onshow, but don't put your code there,
just this

   Application.QueueAsyncCall(@MyProc,0)

then put the cursor on MyProc and press CTRL+SHIFT+C, now lazarus will
automatically declare the MyProc method. You can put your code there.
It will be invoked asynchronously once the form has been shown.
The problem is, while your loop is running the form will be totally
unresponsive, it won't even show the lines you add to the memo.
To avoid it you could either put your code in a thread (difficult) in
order not to stall the gui, or simply call Application.ProcessMessages
from time to time, e.g. when you add a line to the memo.

Bye
--
Luca
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

martin_wynne
In reply to this post by Zaaphod

> The Lazarus version is mostly working in Lazarus, but instead of everything happening before the form is loaded, is there a way I could make the form first, then just start processing everything, so that my messages I send to memo1 show up as it's processing?  I'm guessing I need to move my program from On-create to somewhere else so it runs after the memo box is showing... but I don't know where I would move it to.  Any suggestions?

Hi James,

Move your code to the form's OnActivate event.

cheers,

Martin.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Giuliano Colla
In reply to this post by Zaaphod

Il 03/11/2018 23:16, James ha scritto:

It’s not a snippet, that’s the entire thing.   It’s pretty simple, just a sequential set of events to fix a file.  It would be a great help if you could get me an example of how to make this work.
The simplest thing you can do is just to transform your application into a GUI application.
Try to do the following:

Start your Lazarus, then select Project->New Project -> Application

You get that way an empty form and a skeleton unit.

You'll find that in the var section there's de declaration of Form1, you may add there your var's.

If you want your user to pick up a file name from the file dialog, do the following:
Click on the Dialogs Tab, on the icon "TOpen Dialog", and then click anywhere on the Form.

Now you have an OpenDialog icon on your form, which will not be visible run time. It's there just to let you set its properties in the Object Inspector. You may set there a default extension, an Initial Dir, a default file name, or whatever you think can be useful to the user. Or you may leave the fields empty so that the system defaults are taken. You may also set the OpenDialog File name from the invocation command line: in the initialization section (or in the OnCreate event of the form) you may add OpenDialog1.FileName := ParamStr(1).

Now from the "Standard" Tab click on the TButton Icon and click on the form. You get a Button on the form. Change in the Object Inspector the Caption to what you want, sort of "Select Input File".
In the object Inspector select the Events tab and then the OnClick event. Click on the three periods to the right, and you'll get in the source editor the skeleton of a new procedure (TForm1.Button1Click).

That's where all of your code goes. Typically:

If OpenDialog1.Execute then begin
  TapFileName := OpenDialog1.FileName;
  ......
  etc.

You may add a Tedit (always fron the "Standard" tab) object to show your messages: your writeln becomes  Edit1.Text := 'Whatever'.

Where you need to ask the user for a new filename, you may just call a second time OpenDialog1.execute, to get it.

If you want to be kind to your user, you may add a "Close" button, to close the application when the user is done.
Just pick from the "Aditional" tab a TBitBtn, put it in your form, then in the Object Inspector select the "Kind" as "bkClose".

There's no more than that. You may now save your project, giving the program and the unit some name you like. Then play a bit with it, and adjust following your needs.

Hope that it helps.

Giuliano
-- 
Do not do to others as you would have them do to you.They might have different tastes.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Zaaphod
In reply to this post by Alexander Grotewohl
Thank you for this example!  It works perfectly and I now have my console program putting up message boxes and opening a Save-As box as needed.

James

-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Alexander Grotewohl
Sent: Sunday, November 4, 2018 11:48 AM
To: [hidden email]
Subject: Re: [fpc-pascal] Windows programming tutorials for FPC

Program TestGetSaveFileNameA;
Uses windows, commdlg;

Var
    TFilename                                      : TOpenFileNameA;

    ret: array[0..100] of char;

Begin
    Writeln('Start');

    fillchar(TFileName, sizeof(TFileName), 0);
    TFileName.lStructSize:=sizeof(TFileName);

    TFileName.hwndOwner:=0;
    TFileName.lpstrFile:=ret;
    TFileName.lpstrFile[0]:=#0;
    TFileName.lpstrFilter:='Text Files (*.txt)'+#0+'*.txt'+#0;
    TFileName.nMaxFile:=100;
    TFileName.Flags := OFN_EXPLORER or OFN_FILEMUSTEXIST or OFN_HIDEREADONLY;
    TFileName.lpstrDefExt:='txt';

    Writeln(GetSaveFileNameA(@TFilename));
    Writeln('Finished with '+strpas(TFileName.lpstrFile));
    Readln;
End.


On 11/4/2018 11:21 AM, James wrote:

> This is very interesting, thank you for the code on how to define the GetSaveFileNameA function.  I wrote a sample program to get it to work, but I think I have some syntax wrong, or maybe I'm not initializing something correctly.   It compiles ok, but it doesn't execute even my writeln's, I just get an exit code = 1
>
> James
>
> Program TestGetSaveFileNameA;
> Uses CRT,Classes,Sysutils,windows;
> Type
> TOpenFileNameAHookProc = function(Wnd: HWND; Msg: UINT; wParam:
> WPARAM;
> lParam: LPARAM): UINT stdcall;
>
> TOpenFileNameA = Packed Record
> lStructSize: DWord;
> hWndOwner: HWND;
> hInstance: HINST;
> lpstrFilter: PChar;
> lpstrCustomFilter: PChar;
> nMaxCustFilter: DWord;
> nFilterIndex: DWord;
> lpstrFile: PChar;
> nMaxFile: DWord;
> lpstrFileTitle: PChar;
> nMaxFileTitle: DWord;
> lpstrInitialDir: PChar;
> lpstrTitle: PChar;
> Flags: DWord;
> nFileOffset: Word;
> nFileExtension: Word;
> lpstrDefExt: PChar;
> lCustData: LPARAM;
> lpfnHook: TOpenFileNameAHookProc;
> lpTemplateName: PChar;
> lpEditInfo: Pointer; // Undocumented?
> lpstrPrompt: PChar;
> _Reserved1: Pointer;
> _Reserved2: DWord;
> FlagsEx: DWord;
> End;
> POpenFileNameA = ^TOpenFileNameA;
>
> Function GetSaveFileNameA(arg: POpenFileNameA): windows.bool; stdcall;
> external 'comdlg32' name 'GetSaveFileNameA';
>
> Var
>     TFilename                                      : TOpenFileNameA;
>     PFilename                                      : POpenFileNameA;
>
> Begin
>     Writeln('Start');
>     TFilename.lpstrInitialDir:=Pchar('I:\');
>     Pfilename:=@Tfilename;
>     Writeln(GetSaveFileNameA(PFilename));
>     Writeln('Finished');
>     Readln;
> End.
>
>
>
>
>
> -----Original Message-----
> From: fpc-pascal <[hidden email]> On Behalf
> Of Ewald
> Sent: Sunday, November 4, 2018 8:06 AM
> To: [hidden email]
> Subject: Re: [fpc-pascal] Windows programming tutorials for FPC
>
> On 11/03/2018 09:04 PM, James wrote:
>> So my question is, how can I use Ifilesavedialog with just FreePascal
>> in a console application?
> First off, the IFileSaveDialog is an interface, not a simple function.
> So, you'll need to:
> - Include the right units from freepascal (ActiveX and comobj
>             IIRC)
> - Initialize and finalize the COM subsystem (see CoInitialize
>             and CoUninitialize)
> - Use the CoCreateInstance to instantiate an IFileSaveDialog,
>             etc.. I've never used the IFileSaveDialog myself, so have a
>             look at
> https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913%28v=
> vs.85%29.aspx#usage
>
> That's the nice thing about the GetSaveFileNameA function: one call,
> and you're done :-)
>
> Now, if this function is not defined in the windows unit (which could
> be the case), you can either look into some other units or simply
> define it
> yourself:
>
> === code begin ===
> Type
> TOpenFileNameAHookProc = function(Wnd: HWND; Msg: UINT; wParam:
> WPARAM;
> lParam: LPARAM): UINT stdcall;
>
> TOpenFileNameA = Packed Record
> lStructSize: DWord;
> hWndOwner: HWND;
> hInstance: HINST;
> lpstrFilter: PChar;
> lpstrCustomFilter: PChar;
> nMaxCustFilter: DWord;
> nFilterIndex: DWord;
> lpstrFile: PChar;
> nMaxFile: DWord;
> lpstrFileTitle: PChar;
> nMaxFileTitle: DWord;
> lpstrInitialDir: PChar;
> lpstrTitle: PChar;
> Flags: DWord;
> nFileOffset: Word;
> nFileExtension: Word;
> lpstrDefExt: PChar;
> lCustData: LPARAM;
> lpfnHook: TOpenFileNameAHookProc;
> lpTemplateName: PChar;
> lpEditInfo: Pointer; // Undocumented?
> lpstrPrompt: PChar;
> _Reserved1: Pointer;
> _Reserved2: DWord;
> FlagsEx: DWord;
> End;
> POpenFileNameA = ^TOpenFileNameA;
>
> Function GetSaveFileNameA(arg: POpenFileNameA): windows.bool; stdcall;
> external 'comdlg32' name 'GetSaveFileNameA'; === code end ===
>
>
> --
> Ewald
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Zaaphod
In reply to this post by martin_wynne
Thank you everyone who helped me with this.  I have both the Lazarus version and the FPC console version both working with a Save-As  dialog and message boxes for errors.  Basic functionality is working great with both methods.  Since it's such a simple program, I'll tinker with it with both methods for a while and use it as a learning process.   I am encouraged by getting this to work in Lazarus, so it's probably time I took to time to learn more about it instead of always writing console applications, I can see where it would be great to have some buttons for options and things like that... and at the same time I am thrilled to have such capability in my console applications!  

James
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Zaaphod
In reply to this post by Zaaphod
I've been using the example below to use the Save-as dialog in my console program, and it works great, but I would like to be able to detect if the user pushes either the red X or the cancel button in the dialog.   I am supplying a suggested default name, and what's happening is if the user cancels or hits the red X, it just saves the file using the suggested default name, but the correct behavior would be to not save anything.   I'm not sure how this is normally done with GetSaveFileNameA.


-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Alexander Grotewohl
Sent: Sunday, November 4, 2018 11:48 AM
To: [hidden email]
Subject: Re: [fpc-pascal] Windows programming tutorials for FPC

Program TestGetSaveFileNameA;
Uses windows, commdlg;

Var
    TFilename                                      : TOpenFileNameA;

    ret: array[0..100] of char;

Begin
    Writeln('Start');

    fillchar(TFileName, sizeof(TFileName), 0);
    TFileName.lStructSize:=sizeof(TFileName);

    TFileName.hwndOwner:=0;
    TFileName.lpstrFile:=ret;
    TFileName.lpstrFile[0]:=#0;
    TFileName.lpstrFilter:='Text Files (*.txt)'+#0+'*.txt'+#0;
    TFileName.nMaxFile:=100;
    TFileName.Flags := OFN_EXPLORER or OFN_FILEMUSTEXIST or OFN_HIDEREADONLY;
    TFileName.lpstrDefExt:='txt';

    Writeln(GetSaveFileNameA(@TFilename));
    Writeln('Finished with '+strpas(TFileName.lpstrFile));
    Readln;
End.


On 11/4/2018 11:21 AM, James wrote:

> This is very interesting, thank you for the code on how to define the GetSaveFileNameA function.  I wrote a sample program to get it to work, but I think I have some syntax wrong, or maybe I'm not initializing something correctly.   It compiles ok, but it doesn't execute even my writeln's, I just get an exit code = 1
>
> James
>
> Program TestGetSaveFileNameA;
> Uses CRT,Classes,Sysutils,windows;
> Type
> TOpenFileNameAHookProc = function(Wnd: HWND; Msg: UINT; wParam:
> WPARAM;
> lParam: LPARAM): UINT stdcall;
>
> TOpenFileNameA = Packed Record
> lStructSize: DWord;
> hWndOwner: HWND;
> hInstance: HINST;
> lpstrFilter: PChar;
> lpstrCustomFilter: PChar;
> nMaxCustFilter: DWord;
> nFilterIndex: DWord;
> lpstrFile: PChar;
> nMaxFile: DWord;
> lpstrFileTitle: PChar;
> nMaxFileTitle: DWord;
> lpstrInitialDir: PChar;
> lpstrTitle: PChar;
> Flags: DWord;
> nFileOffset: Word;
> nFileExtension: Word;
> lpstrDefExt: PChar;
> lCustData: LPARAM;
> lpfnHook: TOpenFileNameAHookProc;
> lpTemplateName: PChar;
> lpEditInfo: Pointer; // Undocumented?
> lpstrPrompt: PChar;
> _Reserved1: Pointer;
> _Reserved2: DWord;
> FlagsEx: DWord;
> End;
> POpenFileNameA = ^TOpenFileNameA;
>
> Function GetSaveFileNameA(arg: POpenFileNameA): windows.bool; stdcall;
> external 'comdlg32' name 'GetSaveFileNameA';
>
> Var
>     TFilename                                      : TOpenFileNameA;
>     PFilename                                      : POpenFileNameA;
>
> Begin
>     Writeln('Start');
>     TFilename.lpstrInitialDir:=Pchar('I:\');
>     Pfilename:=@Tfilename;
>     Writeln(GetSaveFileNameA(PFilename));
>     Writeln('Finished');
>     Readln;
> End.
>
>
>
>
>
> -----Original Message-----
> From: fpc-pascal <[hidden email]> On Behalf
> Of Ewald
> Sent: Sunday, November 4, 2018 8:06 AM
> To: [hidden email]
> Subject: Re: [fpc-pascal] Windows programming tutorials for FPC
>
> On 11/03/2018 09:04 PM, James wrote:
>> So my question is, how can I use Ifilesavedialog with just FreePascal
>> in a console application?
> First off, the IFileSaveDialog is an interface, not a simple function.
> So, you'll need to:
> - Include the right units from freepascal (ActiveX and comobj
>             IIRC)
> - Initialize and finalize the COM subsystem (see CoInitialize
>             and CoUninitialize)
> - Use the CoCreateInstance to instantiate an IFileSaveDialog,
>             etc.. I've never used the IFileSaveDialog myself, so have a
>             look at
> https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913%28v=
> vs.85%29.aspx#usage
>
> That's the nice thing about the GetSaveFileNameA function: one call,
> and you're done :-)
>
> Now, if this function is not defined in the windows unit (which could
> be the case), you can either look into some other units or simply
> define it
> yourself:
>
> === code begin ===
> Type
> TOpenFileNameAHookProc = function(Wnd: HWND; Msg: UINT; wParam:
> WPARAM;
> lParam: LPARAM): UINT stdcall;
>
> TOpenFileNameA = Packed Record
> lStructSize: DWord;
> hWndOwner: HWND;
> hInstance: HINST;
> lpstrFilter: PChar;
> lpstrCustomFilter: PChar;
> nMaxCustFilter: DWord;
> nFilterIndex: DWord;
> lpstrFile: PChar;
> nMaxFile: DWord;
> lpstrFileTitle: PChar;
> nMaxFileTitle: DWord;
> lpstrInitialDir: PChar;
> lpstrTitle: PChar;
> Flags: DWord;
> nFileOffset: Word;
> nFileExtension: Word;
> lpstrDefExt: PChar;
> lCustData: LPARAM;
> lpfnHook: TOpenFileNameAHookProc;
> lpTemplateName: PChar;
> lpEditInfo: Pointer; // Undocumented?
> lpstrPrompt: PChar;
> _Reserved1: Pointer;
> _Reserved2: DWord;
> FlagsEx: DWord;
> End;
> POpenFileNameA = ^TOpenFileNameA;
>
> Function GetSaveFileNameA(arg: POpenFileNameA): windows.bool; stdcall;
> external 'comdlg32' name 'GetSaveFileNameA'; === code end ===
>
>
> --
> Ewald
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Santiago A.
In reply to this post by Zaaphod
El 02/11/18 a las 11:13, James escribió:
> I've been programming for decades with Pascal, starting with Turbo Pascal, and for a few years now with Freepascal, and even wrote really complicated console windows programs with Freepascal that do windows function calls... But now I find that I would like to write a few windows GUI programs,  and well... I'm clueless... I never learned windows GUI programming and don't have a clue about how it's done, it's always been faster and easier to just keep doing what I already understand, but now I have a few applications to write what would be much better suited to a native windows application, so,   I am wondering if there are any tutorials out there, hopefully specific to Freepascal and/or Lazarus.  I need really basic stuff like how to open a message box, or how to use windows file open, or save-as dialog boxes.. etc.. even a hello world tutorial would be helpful... ok, so ZERO windows programming experience here...   Any advice on where to start?
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Tutorials? well, that is funny. Usually there are many tutorials the
other way around, that is, young guys that master GUI and must learn
real programming to go further.

I know where you are, because I was there many years ago when I moved
from DOS programming to windows programming. Someone has posted that
programming is programming, no matter GUI or not GUI. Well, yes and no.
You must change your paradigm a little. I suggest you to try Lazarus.

Besides tutorials  and howtos people have posted, let me tell you how I
changed my point of view. Hope it helps you, but I don't expect much,
everybody has his own epiphany ;-).

I started to stop seeing programs as a lineal process. I saw it more
like an iceberg, where the window you see in the GUI is the tip,
whenever you e.i. click a button, the program goes down, gets results
and returns to the tip.

In console programs, you read data one by by one, a prompt and stop
expecting an input. If the input data is wrong you ask it again.
Creating a window with many data allowing the user is complicated, you
must control cursor keys etc, special keys to submit the full form etc,
you must inspect keys pressed by user in a loop. That is the "easy" part
in GUI, using a RAD you create the window in design time, you write the
prompts for data, the font, the position the size, the colors, the
order,  initial values etc, you run de program, and there it is.
(Paradoxically the more you work with GUI,  the more you do in run time
and the less in design time). The GUI is composed by a window and
controls, that are anything on the window, a button, a text written, a
bevel, a box, a check box, a menu,a progress bar, a date prompt... and
hundreds of different controls.

The GUI programming is event driver. That is, the program, the windows,
sits there doing nothing, and reacts to what user does. The user clicks
a button, then the  program performs what it is expected to do and
returns to wait for a user action. That applies to user clicking a
button, or moving the mouse, or typing a key, or even moving a window.
Usually every control has some events, a button a "onClick" event, an
edit box  a "on selected text", and some controls, like a label, may not
have events. The question is that many events are irrelevant to you, the
GUI takes care of them, i.e., you press the key TAB and GUI moves to
other control and you needn't to write a line of code. Or a check box,
when clicked it toggles from checked to not checked for you etc. The GUI
does a bunch of UI things for you. When you want the program to respond
to an event as you want, you create a function and associate it with
that event.

The even effect is accomplished with a queue of messages. That is, when
user click a button, a message is sent to queue, the loop waiting for
messages picks the message from the queue and then executes the action
associated with the click event. Usually you don't have to worry about
this, it is transparent to you. But it is important to understand that
if your event takes a long time, the full GUI will be irresponsive until
it finish, all effects in the GUI are messages in the queue and until it
picks the next messages, nothing happens it is frozen. So, in long
process, you may disable things in the window, to inform the user he
can't do anything, and while doing real work tell the GUI to process
pending messages, so the user doesn't think the program is frozen. You
can also update the window to show progress, but you also must say GUI
to process messages queue, because you updates are just messages to the
window.

A RAD like Lazarus, creates a form, a window, and lets you drop
controls, resize them easily, change some properties, etc. The RAD show
you the events each control has, when you click them, it creates am
empty function and brings to front the editor to let you write the real
code.

It is an over simplification, but hope it has helped a little. But well,
as I said, everybody has his own epiphany. Good luck

--
Saludos

Santiago A.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Alexander Grotewohl
In reply to this post by Zaaphod
This line:

Writeln(GetSaveFileNameA(@TFilename));

What does it write when you select a file vs when you click x/cancel?
:-):-)

On 11/12/2018 4:31 AM, James wrote:

> I've been using the example below to use the Save-as dialog in my console program, and it works great, but I would like to be able to detect if the user pushes either the red X or the cancel button in the dialog.   I am supplying a suggested default name, and what's happening is if the user cancels or hits the red X, it just saves the file using the suggested default name, but the correct behavior would be to not save anything.   I'm not sure how this is normally done with GetSaveFileNameA.
>
>
> -----Original Message-----
> From: fpc-pascal <[hidden email]> On Behalf Of Alexander Grotewohl
> Sent: Sunday, November 4, 2018 11:48 AM
> To: [hidden email]
> Subject: Re: [fpc-pascal] Windows programming tutorials for FPC
>
> Program TestGetSaveFileNameA;
> Uses windows, commdlg;
>
> Var
>      TFilename                                      : TOpenFileNameA;
>
>      ret: array[0..100] of char;
>
> Begin
>      Writeln('Start');
>
>      fillchar(TFileName, sizeof(TFileName), 0);
>      TFileName.lStructSize:=sizeof(TFileName);
>
>      TFileName.hwndOwner:=0;
>      TFileName.lpstrFile:=ret;
>      TFileName.lpstrFile[0]:=#0;
>      TFileName.lpstrFilter:='Text Files (*.txt)'+#0+'*.txt'+#0;
>      TFileName.nMaxFile:=100;
>      TFileName.Flags := OFN_EXPLORER or OFN_FILEMUSTEXIST or OFN_HIDEREADONLY;
>      TFileName.lpstrDefExt:='txt';
>
>      Writeln(GetSaveFileNameA(@TFilename));
>      Writeln('Finished with '+strpas(TFileName.lpstrFile));
>      Readln;
> End.
>
>
> On 11/4/2018 11:21 AM, James wrote:
>> This is very interesting, thank you for the code on how to define the GetSaveFileNameA function.  I wrote a sample program to get it to work, but I think I have some syntax wrong, or maybe I'm not initializing something correctly.   It compiles ok, but it doesn't execute even my writeln's, I just get an exit code = 1
>>
>> James
>>
>> Program TestGetSaveFileNameA;
>> Uses CRT,Classes,Sysutils,windows;
>> Type
>> TOpenFileNameAHookProc = function(Wnd: HWND; Msg: UINT; wParam:
>> WPARAM;
>> lParam: LPARAM): UINT stdcall;
>>
>> TOpenFileNameA = Packed Record
>> lStructSize: DWord;
>> hWndOwner: HWND;
>> hInstance: HINST;
>> lpstrFilter: PChar;
>> lpstrCustomFilter: PChar;
>> nMaxCustFilter: DWord;
>> nFilterIndex: DWord;
>> lpstrFile: PChar;
>> nMaxFile: DWord;
>> lpstrFileTitle: PChar;
>> nMaxFileTitle: DWord;
>> lpstrInitialDir: PChar;
>> lpstrTitle: PChar;
>> Flags: DWord;
>> nFileOffset: Word;
>> nFileExtension: Word;
>> lpstrDefExt: PChar;
>> lCustData: LPARAM;
>> lpfnHook: TOpenFileNameAHookProc;
>> lpTemplateName: PChar;
>> lpEditInfo: Pointer; // Undocumented?
>> lpstrPrompt: PChar;
>> _Reserved1: Pointer;
>> _Reserved2: DWord;
>> FlagsEx: DWord;
>> End;
>> POpenFileNameA = ^TOpenFileNameA;
>>
>> Function GetSaveFileNameA(arg: POpenFileNameA): windows.bool; stdcall;
>> external 'comdlg32' name 'GetSaveFileNameA';
>>
>> Var
>>      TFilename                                      : TOpenFileNameA;
>>      PFilename                                      : POpenFileNameA;
>>
>> Begin
>>      Writeln('Start');
>>      TFilename.lpstrInitialDir:=Pchar('I:\');
>>      Pfilename:=@Tfilename;
>>      Writeln(GetSaveFileNameA(PFilename));
>>      Writeln('Finished');
>>      Readln;
>> End.
>>
>>
>>
>>
>>
>> -----Original Message-----
>> From: fpc-pascal <[hidden email]> On Behalf
>> Of Ewald
>> Sent: Sunday, November 4, 2018 8:06 AM
>> To: [hidden email]
>> Subject: Re: [fpc-pascal] Windows programming tutorials for FPC
>>
>> On 11/03/2018 09:04 PM, James wrote:
>>> So my question is, how can I use Ifilesavedialog with just FreePascal
>>> in a console application?
>> First off, the IFileSaveDialog is an interface, not a simple function.
>> So, you'll need to:
>> - Include the right units from freepascal (ActiveX and comobj
>>              IIRC)
>> - Initialize and finalize the COM subsystem (see CoInitialize
>>              and CoUninitialize)
>> - Use the CoCreateInstance to instantiate an IFileSaveDialog,
>>              etc.. I've never used the IFileSaveDialog myself, so have a
>>              look at
>> https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913%28v=
>> vs.85%29.aspx#usage
>>
>> That's the nice thing about the GetSaveFileNameA function: one call,
>> and you're done :-)
>>
>> Now, if this function is not defined in the windows unit (which could
>> be the case), you can either look into some other units or simply
>> define it
>> yourself:
>>
>> === code begin ===
>> Type
>> TOpenFileNameAHookProc = function(Wnd: HWND; Msg: UINT; wParam:
>> WPARAM;
>> lParam: LPARAM): UINT stdcall;
>>
>> TOpenFileNameA = Packed Record
>> lStructSize: DWord;
>> hWndOwner: HWND;
>> hInstance: HINST;
>> lpstrFilter: PChar;
>> lpstrCustomFilter: PChar;
>> nMaxCustFilter: DWord;
>> nFilterIndex: DWord;
>> lpstrFile: PChar;
>> nMaxFile: DWord;
>> lpstrFileTitle: PChar;
>> nMaxFileTitle: DWord;
>> lpstrInitialDir: PChar;
>> lpstrTitle: PChar;
>> Flags: DWord;
>> nFileOffset: Word;
>> nFileExtension: Word;
>> lpstrDefExt: PChar;
>> lCustData: LPARAM;
>> lpfnHook: TOpenFileNameAHookProc;
>> lpTemplateName: PChar;
>> lpEditInfo: Pointer; // Undocumented?
>> lpstrPrompt: PChar;
>> _Reserved1: Pointer;
>> _Reserved2: DWord;
>> FlagsEx: DWord;
>> End;
>> POpenFileNameA = ^TOpenFileNameA;
>>
>> Function GetSaveFileNameA(arg: POpenFileNameA): windows.bool; stdcall;
>> external 'comdlg32' name 'GetSaveFileNameA'; === code end ===
>>
>>
>> --
>> Ewald
>> _______________________________________________
>> fpc-pascal maillist  -  [hidden email]
>> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>> _______________________________________________
>> fpc-pascal maillist  -  [hidden email]
>> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Zaaphod
Thank you!  I somehow missed the result of the function being the status I was looking for.   I guess the answer was so easy I couldn't see it 😊
-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Alexander Grotewohl
Sent: Monday, November 12, 2018 11:10 AM
To: [hidden email]
Subject: Re: [fpc-pascal] Windows programming tutorials for FPC

This line:

Writeln(GetSaveFileNameA(@TFilename));

What does it write when you select a file vs when you click x/cancel?
:-):-)

On 11/12/2018 4:31 AM, James wrote:

> I've been using the example below to use the Save-as dialog in my console program, and it works great, but I would like to be able to detect if the user pushes either the red X or the cancel button in the dialog.   I am supplying a suggested default name, and what's happening is if the user cancels or hits the red X, it just saves the file using the suggested default name, but the correct behavior would be to not save anything.   I'm not sure how this is normally done with GetSaveFileNameA.
>
>
> -----Original Message-----
> From: fpc-pascal <[hidden email]> On Behalf
> Of Alexander Grotewohl
> Sent: Sunday, November 4, 2018 11:48 AM
> To: [hidden email]
> Subject: Re: [fpc-pascal] Windows programming tutorials for FPC
>
> Program TestGetSaveFileNameA;
> Uses windows, commdlg;
>
> Var
>      TFilename                                      : TOpenFileNameA;
>
>      ret: array[0..100] of char;
>
> Begin
>      Writeln('Start');
>
>      fillchar(TFileName, sizeof(TFileName), 0);
>      TFileName.lStructSize:=sizeof(TFileName);
>
>      TFileName.hwndOwner:=0;
>      TFileName.lpstrFile:=ret;
>      TFileName.lpstrFile[0]:=#0;
>      TFileName.lpstrFilter:='Text Files (*.txt)'+#0+'*.txt'+#0;
>      TFileName.nMaxFile:=100;
>      TFileName.Flags := OFN_EXPLORER or OFN_FILEMUSTEXIST or OFN_HIDEREADONLY;
>      TFileName.lpstrDefExt:='txt';
>
>      Writeln(GetSaveFileNameA(@TFilename));
>      Writeln('Finished with '+strpas(TFileName.lpstrFile));
>      Readln;
> End.
>
>
> On 11/4/2018 11:21 AM, James wrote:
>> This is very interesting, thank you for the code on how to define the GetSaveFileNameA function.  I wrote a sample program to get it to work, but I think I have some syntax wrong, or maybe I'm not initializing something correctly.   It compiles ok, but it doesn't execute even my writeln's, I just get an exit code = 1
>>
>> James
>>
>> Program TestGetSaveFileNameA;
>> Uses CRT,Classes,Sysutils,windows;
>> Type
>> TOpenFileNameAHookProc = function(Wnd: HWND; Msg: UINT; wParam:
>> WPARAM;
>> lParam: LPARAM): UINT stdcall;
>>
>> TOpenFileNameA = Packed Record
>> lStructSize: DWord;
>> hWndOwner: HWND;
>> hInstance: HINST;
>> lpstrFilter: PChar;
>> lpstrCustomFilter: PChar;
>> nMaxCustFilter: DWord;
>> nFilterIndex: DWord;
>> lpstrFile: PChar;
>> nMaxFile: DWord;
>> lpstrFileTitle: PChar;
>> nMaxFileTitle: DWord;
>> lpstrInitialDir: PChar;
>> lpstrTitle: PChar;
>> Flags: DWord;
>> nFileOffset: Word;
>> nFileExtension: Word;
>> lpstrDefExt: PChar;
>> lCustData: LPARAM;
>> lpfnHook: TOpenFileNameAHookProc;
>> lpTemplateName: PChar;
>> lpEditInfo: Pointer; // Undocumented?
>> lpstrPrompt: PChar;
>> _Reserved1: Pointer;
>> _Reserved2: DWord;
>> FlagsEx: DWord;
>> End;
>> POpenFileNameA = ^TOpenFileNameA;
>>
>> Function GetSaveFileNameA(arg: POpenFileNameA): windows.bool;
>> stdcall; external 'comdlg32' name 'GetSaveFileNameA';
>>
>> Var
>>      TFilename                                      : TOpenFileNameA;
>>      PFilename                                      : POpenFileNameA;
>>
>> Begin
>>      Writeln('Start');
>>      TFilename.lpstrInitialDir:=Pchar('I:\');
>>      Pfilename:=@Tfilename;
>>      Writeln(GetSaveFileNameA(PFilename));
>>      Writeln('Finished');
>>      Readln;
>> End.
>>
>>
>>
>>
>>
>> -----Original Message-----
>> From: fpc-pascal <[hidden email]> On Behalf
>> Of Ewald
>> Sent: Sunday, November 4, 2018 8:06 AM
>> To: [hidden email]
>> Subject: Re: [fpc-pascal] Windows programming tutorials for FPC
>>
>> On 11/03/2018 09:04 PM, James wrote:
>>> So my question is, how can I use Ifilesavedialog with just
>>> FreePascal in a console application?
>> First off, the IFileSaveDialog is an interface, not a simple function.
>> So, you'll need to:
>> - Include the right units from freepascal (ActiveX and comobj
>>              IIRC)
>> - Initialize and finalize the COM subsystem (see CoInitialize
>>              and CoUninitialize)
>> - Use the CoCreateInstance to instantiate an IFileSaveDialog,
>>              etc.. I've never used the IFileSaveDialog myself, so have a
>>              look at
>> https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913%28v
>> =
>> vs.85%29.aspx#usage
>>
>> That's the nice thing about the GetSaveFileNameA function: one call,
>> and you're done :-)
>>
>> Now, if this function is not defined in the windows unit (which could
>> be the case), you can either look into some other units or simply
>> define it
>> yourself:
>>
>> === code begin ===
>> Type
>> TOpenFileNameAHookProc = function(Wnd: HWND; Msg: UINT; wParam:
>> WPARAM;
>> lParam: LPARAM): UINT stdcall;
>>
>> TOpenFileNameA = Packed Record
>> lStructSize: DWord;
>> hWndOwner: HWND;
>> hInstance: HINST;
>> lpstrFilter: PChar;
>> lpstrCustomFilter: PChar;
>> nMaxCustFilter: DWord;
>> nFilterIndex: DWord;
>> lpstrFile: PChar;
>> nMaxFile: DWord;
>> lpstrFileTitle: PChar;
>> nMaxFileTitle: DWord;
>> lpstrInitialDir: PChar;
>> lpstrTitle: PChar;
>> Flags: DWord;
>> nFileOffset: Word;
>> nFileExtension: Word;
>> lpstrDefExt: PChar;
>> lCustData: LPARAM;
>> lpfnHook: TOpenFileNameAHookProc;
>> lpTemplateName: PChar;
>> lpEditInfo: Pointer; // Undocumented?
>> lpstrPrompt: PChar;
>> _Reserved1: Pointer;
>> _Reserved2: DWord;
>> FlagsEx: DWord;
>> End;
>> POpenFileNameA = ^TOpenFileNameA;
>>
>> Function GetSaveFileNameA(arg: POpenFileNameA): windows.bool;
>> stdcall; external 'comdlg32' name 'GetSaveFileNameA'; === code end
>> ===
>>
>>
>> --
>> Ewald
>> _______________________________________________
>> fpc-pascal maillist  -  [hidden email]
>> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>> _______________________________________________
>> fpc-pascal maillist  -  [hidden email]
>> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Windows programming tutorials for FPC

Paul Breneman
In reply to this post by Santiago A.
On 11/12/2018 7:05 AM, Santiago A. wrote:

> El 02/11/18 a las 11:13, James escribió:
>> I've been programming for decades with Pascal, starting with Turbo
>> Pascal, and for a few years now with Freepascal, and even wrote really
>> complicated console windows programs with Freepascal that do windows
>> function calls... But now I find that I would like to write a few
>> windows GUI programs,  and well... I'm clueless... I never learned
>> windows GUI programming and don't have a clue about how it's done,
>> it's always been faster and easier to just keep doing what I already
>> understand, but now I have a few applications to write what would be
>> much better suited to a native windows application, so,   I am
>> wondering if there are any tutorials out there, hopefully specific to
>> Freepascal and/or Lazarus.  I need really basic stuff like how to open
>> a message box, or how to use windows file open, or save-as dialog
>> boxes.. etc.. even a hello world tutorial would be helpful... ok, so
>> ZERO windows programming experience here...   Any advice on where to
>> start?
>> _______________________________________________
>> fpc-pascal maillist  -  [hidden email]
>> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>
> Tutorials? well, that is funny. Usually there are many tutorials the
> other way around, that is, young guys that master GUI and must learn
> real programming to go further.
>
> I know where you are, because I was there many years ago when I moved
> from DOS programming to windows programming. Someone has posted that
> programming is programming, no matter GUI or not GUI. Well, yes and no.
> You must change your paradigm a little. I suggest you to try Lazarus.
>
> Besides tutorials  and howtos people have posted, let me tell you how I
> changed my point of view. Hope it helps you, but I don't expect much,
> everybody has his own epiphany ;-).
>
> I started to stop seeing programs as a lineal process. I saw it more
> like an iceberg, where the window you see in the GUI is the tip,
> whenever you e.i. click a button, the program goes down, gets results
> and returns to the tip.
>
> In console programs, you read data one by by one, a prompt and stop
> expecting an input. If the input data is wrong you ask it again.
> Creating a window with many data allowing the user is complicated, you
> must control cursor keys etc, special keys to submit the full form etc,
> you must inspect keys pressed by user in a loop. That is the "easy" part
> in GUI, using a RAD you create the window in design time, you write the
> prompts for data, the font, the position the size, the colors, the
> order,  initial values etc, you run de program, and there it is.
> (Paradoxically the more you work with GUI,  the more you do in run time
> and the less in design time). The GUI is composed by a window and
> controls, that are anything on the window, a button, a text written, a
> bevel, a box, a check box, a menu,a progress bar, a date prompt... and
> hundreds of different controls.
>
> The GUI programming is event driver. That is, the program, the windows,
> sits there doing nothing, and reacts to what user does. The user clicks
> a button, then the  program performs what it is expected to do and
> returns to wait for a user action. That applies to user clicking a
> button, or moving the mouse, or typing a key, or even moving a window.
> Usually every control has some events, a button a "onClick" event, an
> edit box  a "on selected text", and some controls, like a label, may not
> have events. The question is that many events are irrelevant to you, the
> GUI takes care of them, i.e., you press the key TAB and GUI moves to
> other control and you needn't to write a line of code. Or a check box,
> when clicked it toggles from checked to not checked for you etc. The GUI
> does a bunch of UI things for you. When you want the program to respond
> to an event as you want, you create a function and associate it with
> that event.
>
> The even effect is accomplished with a queue of messages. That is, when
> user click a button, a message is sent to queue, the loop waiting for
> messages picks the message from the queue and then executes the action
> associated with the click event. Usually you don't have to worry about
> this, it is transparent to you. But it is important to understand that
> if your event takes a long time, the full GUI will be irresponsive until
> it finish, all effects in the GUI are messages in the queue and until it
> picks the next messages, nothing happens it is frozen. So, in long
> process, you may disable things in the window, to inform the user he
> can't do anything, and while doing real work tell the GUI to process
> pending messages, so the user doesn't think the program is frozen. You
> can also update the window to show progress, but you also must say GUI
> to process messages queue, because you updates are just messages to the
> window.
>
> A RAD like Lazarus, creates a form, a window, and lets you drop
> controls, resize them easily, change some properties, etc. The RAD show
> you the events each control has, when you click them, it creates am
> empty function and brings to front the editor to let you write the real
> code.
>
> It is an over simplification, but hope it has helped a little. But well,
> as I said, everybody has his own epiphany. Good luck
>

Thanks Santiago for all you wrote!

Here is a little that I wrote (back in March 2005):
http://codenewsfast.com/cnf/article/0/permalink.art-ng1824q786

That link appears on this page:
http://www.turbocontrol.com/APro.htm

Regards,
Paul
www.ControlPascal.com
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
12