<div dir="ltr">Hi Phil, Hi All,<div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 28, 2017 at 4:29 AM, <a href="mailto:phil@highoctane.be">phil@highoctane.be</a> <span dir="ltr"><<a href="mailto:phil@highoctane.be" target="_blank">phil@highoctane.be</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<br><br>Pharo is itself a Windows application (under Windows of course).<br><br>So Window event loop is picking up the events and transforming them into Pharo events.<br></div></blockquote><div><br></div><div>Right, but this is *not good enough* :-)  It is a fundamentally different architecture.  The processing of Windows events in the Windows VM transforms *event callbacks* into   an *event queue*.  This is fine for events such as mouse clicks, keyboard presses, etc.  But it is fundamentally broken for events such as those that ask an application to quit because the OS is about to exit, or events that try to obtain mouse feedback while moving a native window, etc, etc.</div><div><br></div><div>So one either needs to extend the VM event queue so that one can install callbacks for certain kinds of events still providing a cross-platform interface), or, as Vassili did for Newspeak native windows (which was fully working in 2008, with the ability to switch a window between emulated (Morphic) and native at will or on image startup), interface to the native Windows event pump via callbacks.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br>You can check this in <a href="https://github.com/pharo-project/pharo-vm" target="_blank">https://github.com/pharo-<wbr>project/pharo-vm</a><br><br>in opensmalltalk-vm\platforms\<wbr>win32\vm\sqWin32Window.c<br><br><a href="https://github.com/pharo-project/pharo-vm/blob/master/opensmalltalk-vm/platforms/win32/vm/sqWin32Window.c" target="_blank">https://github.com/pharo-<wbr>project/pharo-vm/blob/master/<wbr>opensmalltalk-vm/platforms/<wbr>win32/vm/sqWin32Window.c</a><br><br>Like L235...<br><br>LRESULT CALLBACK MainWndProcW(HWND hwnd,<br>UINT message,<br>WPARAM wParam,<br>LPARAM lParam)<br><br>You'll see that we stick a lot of stuff into evt->... in various ways.<div><br></div><div>There is a default fallback at the end.</div><div><br></div><div><table class="m_3068726353635349163gmail-highlight m_3068726353635349163gmail-tab-size m_3068726353635349163gmail-js-file-line-container" style="box-sizing:border-box;border-collapse:collapse;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,"segoe ui",helvetica,arial,sans-serif,"apple color emoji","segoe ui emoji","segoe ui symbol";font-size:14px"><tbody style="box-sizing:border-box"><tr style="box-sizing:border-box"><td id="m_3068726353635349163gmail-LC536" class="m_3068726353635349163gmail-blob-code m_3068726353635349163gmail-blob-code-inner m_3068726353635349163gmail-js-file-line" style="box-sizing:border-box;padding:0px 10px;line-height:20px;vertical-align:top;overflow:visible;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;word-wrap:normal;white-space:pre-wrap"> <span class="m_3068726353635349163gmail-pl-k" style="box-sizing:border-box;color:rgb(167,29,93)">default</span>:</td></tr><tr style="box-sizing:border-box"><td id="m_3068726353635349163gmail-L537" class="m_3068726353635349163gmail-blob-num m_3068726353635349163gmail-js-line-number" style="box-sizing:border-box;padding:0px 10px;width:49.92px;min-width:50px;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;line-height:20px;color:rgba(0,0,0,0.298039);text-align:right;white-space:nowrap;vertical-align:top"></td><td id="m_3068726353635349163gmail-LC537" class="m_3068726353635349163gmail-blob-code m_3068726353635349163gmail-blob-code-inner m_3068726353635349163gmail-js-file-line" style="box-sizing:border-box;padding:0px 10px;line-height:20px;vertical-align:top;overflow:visible;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;word-wrap:normal;white-space:pre-wrap">    <span class="m_3068726353635349163gmail-pl-c" style="box-sizing:border-box;color:rgb(150,152,150)"><span class="m_3068726353635349163gmail-pl-c" style="box-sizing:border-box">/*</span> Unprocessed messages may be processed outside the current</span></td></tr><tr style="box-sizing:border-box"><td id="m_3068726353635349163gmail-L538" class="m_3068726353635349163gmail-blob-num m_3068726353635349163gmail-js-line-number" style="box-sizing:border-box;padding:0px 10px;width:49.92px;min-width:50px;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;line-height:20px;color:rgba(0,0,0,0.298039);text-align:right;white-space:nowrap;vertical-align:top"></td><td id="m_3068726353635349163gmail-LC538" class="m_3068726353635349163gmail-blob-code m_3068726353635349163gmail-blob-code-inner m_3068726353635349163gmail-js-file-line" style="box-sizing:border-box;padding:0px 10px;line-height:20px;vertical-align:top;overflow:visible;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;word-wrap:normal;white-space:pre-wrap"><span class="m_3068726353635349163gmail-pl-c" style="box-sizing:border-box;color:rgb(150,152,150)">       module. If firstMessageHook is non-NULL and returns a non</span></td></tr><tr style="box-sizing:border-box"><td id="m_3068726353635349163gmail-L539" class="m_3068726353635349163gmail-blob-num m_3068726353635349163gmail-js-line-number" style="box-sizing:border-box;padding:0px 10px;width:49.92px;min-width:50px;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;line-height:20px;color:rgba(0,0,0,0.298039);text-align:right;white-space:nowrap;vertical-align:top"></td><td id="m_3068726353635349163gmail-LC539" class="m_3068726353635349163gmail-blob-code m_3068726353635349163gmail-blob-code-inner m_3068726353635349163gmail-js-file-line" style="box-sizing:border-box;padding:0px 10px;line-height:20px;vertical-align:top;overflow:visible;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;word-wrap:normal;white-space:pre-wrap"><span class="m_3068726353635349163gmail-pl-c" style="box-sizing:border-box;color:rgb(150,152,150)">       zero value, the message has been successfully processed <span class="m_3068726353635349163gmail-pl-c" style="box-sizing:border-box">*/</span></span></td></tr><tr style="box-sizing:border-box"><td id="m_3068726353635349163gmail-L540" class="m_3068726353635349163gmail-blob-num m_3068726353635349163gmail-js-line-number" style="box-sizing:border-box;padding:0px 10px;width:49.92px;min-width:50px;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;line-height:20px;color:rgba(0,0,0,0.298039);text-align:right;white-space:nowrap;vertical-align:top"></td><td id="m_3068726353635349163gmail-LC540" class="m_3068726353635349163gmail-blob-code m_3068726353635349163gmail-blob-code-inner m_3068726353635349163gmail-js-file-line" style="box-sizing:border-box;padding:0px 10px;line-height:20px;vertical-align:top;overflow:visible;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;word-wrap:normal;white-space:pre-wrap">    <span class="m_3068726353635349163gmail-pl-k" style="box-sizing:border-box;color:rgb(167,29,93)">if</span>(firstMessageHook)</td></tr><tr style="box-sizing:border-box"><td id="m_3068726353635349163gmail-L541" class="m_3068726353635349163gmail-blob-num m_3068726353635349163gmail-js-line-number" style="box-sizing:border-box;padding:0px 10px;width:49.92px;min-width:50px;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;line-height:20px;color:rgba(0,0,0,0.298039);text-align:right;white-space:nowrap;vertical-align:top"></td><td id="m_3068726353635349163gmail-LC541" class="m_3068726353635349163gmail-blob-code m_3068726353635349163gmail-blob-code-inner m_3068726353635349163gmail-js-file-line" style="box-sizing:border-box;padding:0px 10px;line-height:20px;vertical-align:top;overflow:visible;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;word-wrap:normal;white-space:pre-wrap">      <span class="m_3068726353635349163gmail-pl-k" style="box-sizing:border-box;color:rgb(167,29,93)">if</span>((*firstMessageHook)(hwnd, message, wParam, lParam))</td></tr><tr style="box-sizing:border-box"><td id="m_3068726353635349163gmail-L542" class="m_3068726353635349163gmail-blob-num m_3068726353635349163gmail-js-line-number" style="box-sizing:border-box;padding:0px 10px;width:49.92px;min-width:50px;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;line-height:20px;color:rgba(0,0,0,0.298039);text-align:right;white-space:nowrap;vertical-align:top"></td><td id="m_3068726353635349163gmail-LC542" class="m_3068726353635349163gmail-blob-code m_3068726353635349163gmail-blob-code-inner m_3068726353635349163gmail-js-file-line" style="box-sizing:border-box;padding:0px 10px;line-height:20px;vertical-align:top;overflow:visible;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;word-wrap:normal;white-space:pre-wrap"> <span class="m_3068726353635349163gmail-pl-k" style="box-sizing:border-box;color:rgb(167,29,93)">return</span> <span class="m_3068726353635349163gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,134,179)">1</span>;</td></tr><tr style="box-sizing:border-box"><td id="m_3068726353635349163gmail-L543" class="m_3068726353635349163gmail-blob-num m_3068726353635349163gmail-js-line-number" style="box-sizing:border-box;padding:0px 10px;width:49.92px;min-width:50px;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;line-height:20px;color:rgba(0,0,0,0.298039);text-align:right;white-space:nowrap;vertical-align:top"></td><td id="m_3068726353635349163gmail-LC543" class="m_3068726353635349163gmail-blob-code m_3068726353635349163gmail-blob-code-inner m_3068726353635349163gmail-js-file-line" style="box-sizing:border-box;padding:0px 10px;line-height:20px;vertical-align:top;overflow:visible;font-family:sfmono-regular,consolas,"liberation mono",menlo,courier,monospace;font-size:12px;word-wrap:normal;white-space:pre-wrap">    <span class="m_3068726353635349163gmail-pl-k" style="box-sizing:border-box;color:rgb(167,29,93)">return</span> <span class="m_3068726353635349163gmail-pl-c1" style="box-sizing:border-box;color:rgb(0,134,179)">DefWindowProcW</span>(hwnd,message,<wbr>wParam,lParam);


</td></tr></tbody></table><br><br>{<br><br><br>So, if firstMessageHook exists, one can do whatever.</div><div><br></div><div>Now, a Windows manager may need other stuff and so on.</div><div>What you are looking at is how to hook this VM side with more of the general Windows system.</div><div><br></div><div>These hooks are globals, so should be accessible.</div><div></div><br>/*****************************<wbr>******************************<wbr>*****************/<br>/* Message Processing */<br>/*****************************<wbr>******************************<wbr>*****************/<br>/* The last dispatched event. It is used for the event processing mechanism. */<br>MSG *lastMessage = NULL;<br>/* The entry to the message hooks called from the window procedure.<br>If another module requires to process messages by itself, it should<br>put its message procedure in this place. */<br>messageHook firstMessageHook = 0;<br>/* The entry to a pre-message hook. Can be used to intercept any messages<br>to the squeak main window. Useful for modules that wish to be notified<br>about certain messages before they are processed. */<br>messageHook preMessageHook = 0;<div><br></div><div>Never played with these but any Windows integration is of interest to me.</div><div><br></div><div>So, go ahead. Nothing would resist focused work.</div><div><br></div><div>Be aware that there is another VM underway with a cleanup of all of this but this is not released yet.</div><div><br></div><div>Keep us posted.</div><div><span class="HOEnZb"><font color="#888888">Phil</font></span><div><div class="h5"><br><br><br><br>On Tue, Feb 28, 2017 at 9:33 AM, Torsten Bergmann <<a href="mailto:astares@gmx.de" target="_blank">astares@gmx.de</a>> wrote:<br>><br>> Hi,<br>><br>> I guess what you want to achieve will not be an easy task for you if you are new to programming.<br>> But it is always good to have a goal and if you have time to learn I'm pretty sure you will master<br>> it.<br>><br>> Even when OS-Windows inspire you for automizing tasks in other Windows processes (like autoit) you<br>> should not start with my OS-Windows project directly as contributing to it requires knowledge<br>> on your side on Smalltalk as well as Win32 C programming.<br>><br>> First start with learning Smalltalk and Pharo<br>>   - <a href="http://files.pharo.org/books/" target="_blank">http://files.pharo.org/books/</a><br>>   - <a href="http://pharo.pharocloud.com/pharobooks" target="_blank">http://pharo.pharocloud.com/<wbr>pharobooks</a><br>>   - <a href="http://stephane.ducasse.free.fr/FreeBooks.html" target="_blank">http://stephane.ducasse.free.<wbr>fr/FreeBooks.html</a><br>><br>> After having an idea about Smalltalk and Pharo you should try to learn UFFI which<br>> is Pharos unified foreign function interface and ability to call C DLL's.<br>><br>> <a href="https://ci.inria.fr/pharo-contribution/view/Books/job/PharoBookWorkInProgress/lastSuccessfulBuild/artifact/book-result/UnifiedFFI/" target="_blank">https://ci.inria.fr/pharo-<wbr>contribution/view/Books/job/<wbr>PharoBookWorkInProgress/<wbr>lastSuccessfulBuild/artifact/<wbr>book-result/UnifiedFFI/</a><br>><br>> Sideways start learning about the Win32 API and C as this helps to better understand<br>> how things are done on the Windows side. There are many, many tutorials out there.<br>> Try to call or wrap some simple DLL functions on you own first.<br>><br>> There is a nice and tiny C compiler if you want to try out some C samples<br>> <a href="http://www.pellesc.de/index.php?page=download&lang=en" target="_blank">http://www.pellesc.de/index.<wbr>php?page=download&lang=en</a><br>><br>> With this initial knowledge you can try to understand why and how OS-Windows was done.<br>> I wrote many tests - just add a breakpoint and run them to debug through the code to understand.<br>> Google for the API descriptions of the Win32 functions that are called to get an understanding<br>> how Pharo and C get connected.<br>><br>> Also check how you work with callbacks in UFFI (as this would be required for a hook).<br>><br>> If you are then still interested in interception windows messages you should start reading here<br>> <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms632589(v=vs.85).aspx" target="_blank">https://msdn.microsoft.com/en-<wbr>us/library/windows/desktop/<wbr>ms632589(v=vs.85).aspx</a><br>><br>> Primarily one has to wrap SetWindowsHookEx API function and friends and wrap a good API<br>> for them in Pharo.<br>><br>> Hope that helps to get started.<br>><br>> Regards<br>> Torsten<br>><br>> > Gesendet: Dienstag, 28. Februar 2017 um 06:04 Uhr<br>> > Von: lw1990 <<a href="mailto:lukewallace1990@gmail.com" target="_blank">lukewallace1990@gmail.com</a>><br>> > An: <a href="mailto:pharo-dev@lists.pharo.org" target="_blank">pharo-dev@lists.pharo.org</a><br>> > Betreff: [Pharo-dev] How to listen for windows messages?<br>> ><br>> > In the OS-Windows package, there exists the ability to use the windows api in<br>> > Pharo.<br>> > This is very powerful, and I intend to add more of the windows api into it<br>> > (it's only partially implemented).<br>> ><br>> > This appears to all have been done with DllCalls (FFI calls) so far.<br>> ><br>> > A big part of interacting with windows is listening to/intercepting and<br>> > responding to windows messages.<br>> > For example, every time a user presses a key on the keyboard, a windows<br>> > message will happen in the background for that key. If Pharo was aware of<br>> > these messages, then Pharo could do things in response to hotkeys pressed on<br>> > Windows (outside of a pharo window).<br>> ><br>> > It would also make reacting to events potentially nicer. Like making a<br>> > windows-desktop-manager in Pharo that can tell when a new window is created<br>> > by windows (maybe they opened notepad). It would certainly be better than an<br>> > infinite loop or timer of 'get active window and compare to last active<br>> > window and see if it changed'. Instead it would be 'when receive the<br>> > WM_MESSAGE for new window created, notify Pharo so it can react'.<br>> ><br>> > How can I set up a windows message hook in Pharo?<br>> > Please keep in mind I'm very new to programming, but I work from home and<br>> > have lots of time to learn :-)<br>> ><br>> ><br>> ><br>> > --<br>> > View this message in context: <a href="http://forum.world.st/How-to-listen-for-windows-messages-tp4936285.html" target="_blank">http://forum.world.st/How-to-<wbr>listen-for-windows-messages-<wbr>tp4936285.html</a><br>> > Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.<br>> ><br>> ><br>><br></div></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>