Recent

Author Topic: Porting Win32 code to Apple Mac  (Read 6013 times)

carl_caulkett

  • Sr. Member
  • ****
  • Posts: 306
Porting Win32 code to Apple Mac
« on: August 17, 2017, 08:53:36 pm »
Hello, I've got some code that I'm trying to port to the Apple Mac. It makes use of Windows messages and I'm not sure what is the recommended way of achieving the same results on an Apple Mac, and indeed on non-Windows environments in general.

This is the code in question:

Code: Pascal  [Select][+][-]
  1.  
  2. TcaDiagramElement = class(TcaSizeMovePanel)
  3.   private
  4.     // Property fields
  5.     FCenterPoint: TPoint;
  6.     FOldLeft: Integer;
  7.     FOldTop: Integer;
  8.     // Private methods
  9.     procedure UpdateCenterPoint;
  10.     procedure WMWindowPosChanging(var Message: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
  11.     procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED;
  12.  

Code: Pascal  [Select][+][-]
  1. procedure TcaDiagramElement.WMWindowPosChanging(var Message: TWMWindowPosChanging);
  2. begin
  3.   inherited;
  4.   ...
  5. end;
  6.  
  7. procedure TcaDiagramElement.WMWindowPosChanged(var Message: TWMWindowPosChanged);
  8. begin
  9.   inherited;
  10.   ...
  11. end;
  12.  

I notice that my copy of nonwin32/messages.pp translates from WM_ messages to LM_ (Lazarus Message?) and that the lcl/lmessages.pp seems to have routines to handle these messages but I am not sure how to use these. Can any one help? Thanks.
« Last Edit: August 17, 2017, 09:11:02 pm by carl_caulkett »
"It builds... ship it!"

Mac Mini M1
macOS 13.6 Ventura
Lazarus 2.2.6 (release version)
FPC 3.2.2 (release version)

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Porting Win32 code to Apple Mac
« Reply #1 on: August 17, 2017, 09:13:11 pm »

Code: Pascal  [Select][+][-]
  1. uses LMessages, LCLIntf, LCLType .....;
  2. TcaDiagramElement = class(TcaSizeMovePanel)
  3.   private
  4.     // Property fields
  5.     FCenterPoint: TPoint;
  6.     FOldLeft: Integer;
  7.     FOldTop: Integer;
  8.     // Private methods
  9.     procedure UpdateCenterPoint;
  10.    procedure WMWindowPosChanging(var Message: TLMWindowPosChanging); message LM_WINDOWPOSCHANGING;
  11.    procedure WMWindowPosChanged(var Message: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED;
  12.  
1) always use the lcl triad (LMessages, LCLIntf, LCLType) when converting code from windows to lcl.
2) simple change the wm_ to lm_ and twmxx to tlmxxx if the message type do not exist then they are not supported and you need implement it your self for each widget set you want to support (windows, cocoa, qt etc). if the message record does not exists, try using the generic TLMessage and parse the data manually (have a look on the specific records for an idea on how it works) or simple define it (as long as the lm_xxx message is supported).
3) the procedure name is irrelevant, name it what ever you want, it is traditionally named after the message type so you know what it handles, but as far as I know it is not a requirement.
« Last Edit: August 17, 2017, 09:14:58 pm by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

carl_caulkett

  • Sr. Member
  • ****
  • Posts: 306
Re: Porting Win32 code to Apple Mac
« Reply #2 on: August 17, 2017, 09:34:48 pm »
Excellent! Thanks, Taazz, I'll give that a go.
"It builds... ship it!"

Mac Mini M1
macOS 13.6 Ventura
Lazarus 2.2.6 (release version)
FPC 3.2.2 (release version)

carl_caulkett

  • Sr. Member
  • ****
  • Posts: 306
Re: Porting Win32 code to Apple Mac
« Reply #3 on: August 17, 2017, 09:53:39 pm »
I've just found another message handler but I think this one is a bit more tricky, as there doesn't seem to be a direct non-windows equivalent.

Code: Pascal  [Select][+][-]
  1.    
  2. procedure WMExitSizeMove(var Msg: TMessage); message WM_EXITSIZEMOVE;
  3.  

Trouble is that it's several years since I wrote the original code and it's a struggle to persuade the old brain cells to recall what I was trying to do exactly!
"It builds... ship it!"

Mac Mini M1
macOS 13.6 Ventura
Lazarus 2.2.6 (release version)
FPC 3.2.2 (release version)

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Porting Win32 code to Apple Mac
« Reply #4 on: August 17, 2017, 10:50:37 pm »
I've just found another message handler but I think this one is a bit more tricky, as there doesn't seem to be a direct non-windows equivalent.

Code: Pascal  [Select][+][-]
  1.    
  2. procedure WMExitSizeMove(var Msg: TMessage); message WM_EXITSIZEMOVE;
  3.  

Trouble is that it's several years since I wrote the original code and it's a struggle to persuade the old brain cells to recall what I was trying to do exactly!
As far as I can see (didn't look hard enough) it is not supported. Depending on the code in the handler you might be able to use the the poschanged message or you could emulate it. based on the MSDN description https://msdn.microsoft.com/en-us/library/windows/desktop/ms632623(v=vs.85).aspx
Quote
Sent one time to a window, after it has exited the moving or sizing modal loop
The easiest way to emulate it would be to use the Application.QueueAsyncCall to have the application call your function when all other messages have been processed. That would emulate the logic but probably not the timing. The problem is that if you are using it to capture the end of resize instead of the end of a move, you will have to override the lm_size event to queue the call instead of the LM_WindowPosChanged or both.
the more appropriate way to emulate it is to override the default message handling procedure for your control and make sure that the wm_ExitSizeMove message propagated down the processing line and in none windows platforms see how are the rest of the messages emulated and append this one as well. Sorry I have no idea how they are emulated never looked it up.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

carl_caulkett

  • Sr. Member
  • ****
  • Posts: 306
Re: Porting Win32 code to Apple Mac
« Reply #5 on: August 17, 2017, 11:24:35 pm »
No worries. I suspect that code was written shortly after I discovered how to work with Windows messages, and gripped with enthusiasm for my new found skills, I probably decided that everything should be done with Windows messages, ignoring some perfectly usable virtual methods! I reckon I might be able to get round this problem by overriding SetBounds.
"It builds... ship it!"

Mac Mini M1
macOS 13.6 Ventura
Lazarus 2.2.6 (release version)
FPC 3.2.2 (release version)

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Porting Win32 code to Apple Mac
« Reply #6 on: August 18, 2017, 12:01:45 am »
ignoring some perfectly usable virtual methods! I reckon I might be able to get round this problem by overriding SetBounds.

Perhaps as kind of a cautionary tale, you might want to look at a couple of packages I ported many years ago:

http://wiki.lazarus.freepascal.org/OrphPort
http://wiki.lazarus.freepascal.org/THtmlPort

They both have a special unit (MyMisc.pas or HtmlMisc.pas) that attempts to supply the missing Win32 stuff that these packages relied on. (In both cases, the authors treated the Win32 API as though it were normal RTL. Glad those days are over.)

I was never happy with the resulting ports and I never used either for anything.

I think now a better approach might just be to rewrite your code properly cross-platform rather than trying to port something that was never intended to run on other platforms. Just decide what you want the code to do and then look around at how other packages do cross-platform. There are lots of good examples, and also stiff some not-so-good ones.


carl_caulkett

  • Sr. Member
  • ****
  • Posts: 306
Re: Porting Win32 code to Apple Mac
« Reply #7 on: August 18, 2017, 12:45:47 am »
Wise words Phil! In fact, I've weeded out over 50% of my old Delphi library for precisely that reason - some of the code was quite nice but it did rely very heavily on the Win32 API. There are one or two units such as the one I'm looking at currently that I would like to port. I take your point about not trying to do a line by line port, though.
« Last Edit: August 18, 2017, 12:57:16 am by carl_caulkett »
"It builds... ship it!"

Mac Mini M1
macOS 13.6 Ventura
Lazarus 2.2.6 (release version)
FPC 3.2.2 (release version)

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Porting Win32 code to Apple Mac
« Reply #8 on: August 18, 2017, 06:26:02 pm »
I think now a better approach might just be to rewrite your code properly cross-platform rather than trying to port something that was never intended to run on other platforms. Just decide what you want the code to do and then look around at how other packages do cross-platform. There are lots of good examples, and also stiff some not-so-good ones.
Sorry no, the main reasons that win32 was used instead of vcl where 2
1) vcl did not offer any support for the functionality.
2) vcl did not allow proper parametrization of the functionality.

For an example of 1 take a look on USB insert notification. There is nothing in lcl that supports it.
For an example of 2 take a look on the wacky resize/move internal mechanism of lcl, the developers made sure I can not override its behavior in my components. So win32 to avoid any and all infinite loop exceptions.

Sorry but no, "that times" are not over yet lcl has a lot of maturity to do at the current pace of things I would say an other 5 years at least.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Porting Win32 code to Apple Mac
« Reply #9 on: August 18, 2017, 09:07:26 pm »
Sorry but no, "that times" are not over yet lcl has a lot of maturity to do at the current pace of things I would say an other 5 years at least.

Yes, I suppose you're right. A good example is the ScrollWindow Win32 API function:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb787591(v=vs.85).aspx

Back when I ported the Orpheus table (grid) control, this was not implemented on any non-Windows widgetset. Now I see that it has been implemented for most widgetsets, although GTK never got it. In fact, I see that Carbon has two versions of ScrollWindow, one that only gets used if you define NewScrollWindowEx when you build the Carbon LCL (meaning no one has ever used it). And Cocoa still doesn't have ScrollWindow implemented, which probably explains why TStringGrid is only partially function on Cocoa (TStringGrid now uses ScrollWindow too).

So a decade after I ported Orpheus, have things improved much with LCL? Well, not so much for Mac users, but certainly GTK2 was a big step up over GTK (Windows has always been pretty solid).

So what's a user to do? Probably three choices:
(1) Use LCL and hope you don't run into an insurmountable obstacle.
(2) Use a non-LCL approach (for example, Xcode + FPC).
(3) Move on to a non-Pascal tool.

In the Mac world, there are a few hardy souls who went with (2), but I would guess most pass on without much complaint to (3).

Actually, there's kind of (1a) that you can use by taking a page from the LCL playbook. That is, create custom controls for what you need and only implement them for the platforms you're interested in. So, for example, I created TWebBrowser for use with Cocoa. Since Qt4 was easy to implement, I did it too, but currently I'm kind of indifferent to the other widgetsets. After all, all anyone has to do is implement the platform-specific part of TWebBrower to use it with their widgetset, just as "all" a Mac user has to do is implement ScrollWindow and the other bits to use the full LCL.

MISV

  • Hero Member
  • *****
  • Posts: 783
Re: Porting Win32 code to Apple Mac
« Reply #10 on: November 16, 2017, 10:12:04 pm »
For what it is worth - I have ported a huge project Delphi/VCL from Windows to Mac using LCL/Carbon - I have the same codebase compiling on both. Overall strongly preferably compared to converting Delphi/VCL to Delphi/Firemonkey (which would mean rewriting a ton of code - it has a huge userinterface) - especially if you need to develop on same codebase while you are converting. Just saying this to say - yes - maybe things could be improved, but I am fairly happy compared to the alternative I was given

 

TinyPortal © 2005-2018