Exploring System Port
[1/17] from: rotenca::telvia::it at: 13-Oct-2002 10:42
get-modes system/ports/system get-modes system/ports/system 'system-modes
== [window: 688 winmsg: [] endian: little]
that window value seems an ID, it is always different.
---
Ciao
Romano
[2/17] from: g:santilli:tiscalinet:it at: 13-Oct-2002 11:47
Hi Romano,
On Sunday, October 13, 2002, 10:42:58 AM, you wrote:
RPT> get-modes system/ports/system get-modes system/ports/system 'system-modes
RPT> == [window: 688 winmsg: [] endian: little]
Very interesting information. I assume the window ID refers to the
console window? Did you find any way to get that for a /View
window?
I wonder if anyone knows what could be set in WINMSG; what type of
messages does Windows send? Maybe we can figure how it works by
ourselves, so that Carl doesn't have to spend precious time in
writing examples... :-)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[3/17] from: petr:krenzelok:trz:cz at: 13-Oct-2002 12:20
Gabriele Santilli wrote:
>Hi Romano,
>On Sunday, October 13, 2002, 10:42:58 AM, you wrote:
<<quoted lines omitted: 7>>
>ourselves, so that Carl doesn't have to spend precious time in
>writing examples... :-)
I asked yesterday Carl to post some example, as I saw ppl here not being
able to proceed with system port usage. Now it is our turn :-) As for
Winmsgs, it should be available somewhere in Win32 API reference manuals
imo ...
-pekr-
[4/17] from: greggirwin:mindspring at: 13-Oct-2002 14:47
Gabriele, et al
Just saw the message from Carl, and need to dig into this more but...
<< Very interesting information. I assume the window ID refers to the
console window? Did you find any way to get that for a /View
window? >>
You're right. Even if no console window is displayed, that's what it
returns. If you know the title of your view window, you can get it with the
API, and I just checked something else. The class name for the console
window is "REBOL", but view windows use "REBOLWind" as a class name so you
could find them that way as well.
<< I wonder if anyone knows what could be set in WINMSG; what type of
messages does Windows send? Maybe we can figure how it works by
ourselves, so that Carl doesn't have to spend precious time in
writing examples... :-) >>
I'll need to play with this on the REBOL side, but Windows messages follow a
standard format. There are 3 parts to a message, with the target window
handle being a fourth, if you use something like the SendMessage API. The 3
component parts of a message are:
MsgID - This is the numeric ID of the message
wParam - A value that goes with the message. Varies by message type.
Used to be a 16 bit word. It's a 32-bit DWORD under Win32.
lParam - A value, or pointer to a value, that is used by the message.
also varies by message type. 32 bit DWORD
Internally, the OS will also have a timestamp and cursor location for each
message that is sent or queued.
--Gregg
[5/17] from: greggirwin:mindspring at: 13-Oct-2002 17:07
Hi All,
OK, it looks like incoming Windows messages are formed like this:
msg: [winmsg 563 8585228 0]
so:
msg/1 = 'winmsg
msg/2 = ID
msg/3 = wParam
msg/4 = lParam
Below is a very quick hack that allows you to drag and drop files onto the
console window. Requires View/Pro or /Command for library access and a
version that supports the system port (e.g. 1.2.5, 1.2.8, Command 2.1.1).
Let me know if it works for you.
--Gregg
P.S. Watch for wrap!
REBOL [
Title: "sys-port-drag-accept"
File: %sys-port-drag-accept.r
Author: "Gregg Irwin"
EMail: [greggirwin--acm--org]
Purpose: {Demo using system port to catch WM_DROPFILE messages.}
]
; Stripped version of win-shell object for demo purposes.
win-shell: make object! [
win-lib: load/library %shell32.dll
null-buff: func [
{Returns a null-filled string buffer of the specified length.}
len [integer!]
][
head insert/dup make string! len #"^@" len
]
drag-accept-files: make routine! [
hWnd [integer!]
fAccept [integer!]
return: [integer!]
] win-lib "DragAcceptFiles"
drag-finish: make routine! [
hDrop [integer!]
return: [integer!]
] win-lib "DragFinish"
drag-query-file: make routine! [
hWnd [integer!]
iFile [integer!]
lpszFile[string!]
cb [integer!]
return: [integer!]
] win-lib "DragQueryFile"
drag-query-filename-size: make routine! [
hWnd [integer!]
iFile [integer!]
lpszFile[integer!]
cb [integer!]
return: [integer!]
] win-lib "DragQueryFile"
num-files-dropped?: func [hdrop [integer!]] [
drag-query-file hdrop -1 "" 0
]
; When they give us a filename index, we'll subtract one for them,
; because Windows has the list as zero based, but I'd much rather let
; everything be one based on the REBOL side.
dropped-filename-size?: func [hdrop [integer!] index [integer!]] [
drag-query-filename-size hdrop index - 1 0 0
]
dropped-filename?: func [hdrop [integer!] index [integer!] /local result
len] [
result: null-buff add 1 dropped-filename-size? hdrop index
len: drag-query-file hdrop index - 1 result length? result
copy/part result len
]
]
my-hwnd?: does [second get-modes system/ports/system [window]]
WM_DROPFILES: 563 ; &H233
enable-system-trap: does [
; Trap OS interrupts
if not system/ports/system [
if none? attempt [system/ports/system: open [scheme: 'system]][
print "NOTE: Missing System Port" exit
]
]
if find get-modes system/ports/system 'system-modes 'winmsg [
set-modes system/ports/system [winmsg: WM_DROPFILES]
]
append system/ports/wait-list system/ports/system
]
check-system-trap: func [port /local msg] [
if not port? port [return none]
if any [port/scheme <> 'system port <> system/ports/system][return
port]
if not system/ports/system [return none]
while [msg: pick system/ports/system 1] [
;print ["msg:" mold msg]
if msg/1 = 'winmsg [
if msg/2 = WM_DROPFILES [
print ["You dropped " win-shell/num-files-dropped? msg/3
files.
]
repeat i win-shell/num-files-dropped? msg/3 [
file: to-rebol-file win-shell/dropped-filename? msg/3 i
print [tab join i "." tab either dir? file [dirize
file][file]]
]
print "Finishing drag operation"
win-shell/drag-finish msg/3
print "Unregistering window from DragAcceptFiles queue"
win-shell/drag-accept-files my-hwnd? to integer! false
; (save files here)
halt ;quit
]
]
]
none
]
print "Drag some files and drop them on this window...^/"
win-shell/drag-accept-files my-hwnd? to integer! true
enable-system-trap
forever [
wake-port: wait 10 ;timeout period
if wake-port [check-system-trap wake-port]
]
[6/17] from: brett:codeconscious at: 14-Oct-2002 10:30
Hi Gregg,
> Below is a very quick hack that allows you to drag and drop files onto the
> console window. Requires View/Pro or /Command for library access and a
> version that supports the system port (e.g. 1.2.5, 1.2.8, Command 2.1.1).
Scary.... it works. Thanks for doing the decode effort and sharing it.
Regards,
Brett.
[7/17] from: rotenca:telvia:it at: 14-Oct-2002 12:35
Good work Gregg, thanks!
If you know windows-msg, can you tell us what msg could be useful?
And there is something that can be usefule in the Rebol View (not
command/pro)?
---
Ciao
Romano
[8/17] from: greggirwin:mindspring at: 14-Oct-2002 9:40
Hi Romano,
<< If you know windows-msg, can you tell us what msg could be useful? >>
Well, given the volume of Windows messages, you really need to know what it
is you want to accomplish because most of them exist for a reason, so
they're all useful in some context. :)
WM_GETMINMAXINFO - Used to constrain windows sizes as user drags them.
WM_NCxxx - NonClient area messages. Used to do custom painting of title bar,
add custom title bar buttons, etc.
WM_POWERBROADCAST - This is used on battery powered devices to get info
about battery state, when a power is low and shutting things down, etc.
WM_COMMAND - For menu commands and accelerators.
WM_MOUSEHOVER/WM_MOUSELEAVE - If all faces are implemented as true windows,
you could get hover/leave notification.
Some APIs allow you to specify your own callback message (e.g.
Shell_NotifyIcon for tray icon support and SHAppBarMessage for AppDesktopBar
support). Another important use is the case where you have mulitple apps
that talk to each other by pumping messages. Those are generally custom
messages, but it would allow you to use a REBOL app under those
circumstances.
An old trick people would use was to post a message to themselves, rather
than setting up a timer and state flag, to emulate a notification system,
but I never really liked it much.
<< And there is something that can be usefule in the Rebol View (not
command/pro)? >>
Lots of things will require the use of structures, even if they don't use
APIs, which I think is not available in standard View, correct?
WM_POWERBROADCAST is a simple one, though I don't know how useful it is. I
chose WM_DROPFILES because, even though it requires /Pro, it provides a
really handy piece of functionality. With some other API calls you can make
it work for View windows too.
I think RT has actually done a very nice job covering the most useful things
themselves. E.g. insert-event-func let's you catch resize, offset, and close
events.
I've got a little launcher that emulates an AppBar (like the task bar) in
auto-hide mode. The difference being that a real AppDesktopBar modifies the
workspace
of the desktop so maximized apps don't cover them, etc. AppBars
never really took off. Very few companies I know of produce apps that use
them, maybe because the APIs to do so are such a big pain in the butt. :)
Maybe, like the Unix signal stuff, one of the most useful things would be
catching WM_DESTROY so you can clean things up if the session is shutting
down.
--Gregg
[9/17] from: rotenca:telvia:it at: 14-Oct-2002 19:15
Hi Gregg,
thanks again for all your work.
> An old trick people would use was to post a message to themselves, rather
> than setting up a timer and state flag, to emulate a notification system,
> but I never really liked it much.
Not being Windows a real time system, it makes no great difference, a part
adding a bit of confusion to an already caotic system :-)
In Amiga should be another tale.
> << And there is something that can be usefule in the Rebol View (not
> command/pro)? >>
>
> Lots of things will require the use of structures, even if they don't use
> APIs, which I think is not available in standard View, correct?
Structure are also in the plain version of View (and Core i think).
But not library! and routine!.
So i think that a Window message could at least be decoded and read if it does
not require other system calls.
---
Ciao
Romano
[10/17] from: greggirwin:mindspring at: 14-Oct-2002 12:02
<< Structure are also in the plain version of View (and Core i think).
But not library! and routine!. >>
I couldn't make a struct! in Core, but I could in View.
--Gregg
[11/17] from: atruter:hih:au at: 15-Oct-2002 11:26
> Well, given the volume of Windows messages, you really need to know what
it
> is you want to accomplish because most of them exist for a reason, so
> they're all useful in some context. :)
I don't suppose there is a handy one for "create a short-cut on the
desktop" regardless of what Windows version it is? ;)
Regards,
Ashley
[12/17] from: james:mustard at: 15-Oct-2002 16:38
Ashley wrote:
> I don't suppose there is a handy one for "create a short-cut on the
> desktop" regardless of what Windows version it is? ;)
The easiest way I know of (which doesn't depend on esoteric fCreateShell dll
calls) is to call a windows scripting object file (a *.sh text file) which
will get run by the windows scripting host (provided it is installed -
default in win98 SE upwards - IIRC).
then from rebol its a simple shell call using the ShellExecute API
specifying the name of the script to call.
a sample script file (sample.sh) could contain:
' ------------------------------------------
Set WSHShell = WScript.CreateObject("WScript.Shell")
DesktopPath = WSHShell.SpecialFolders("Desktop")
'Create shortcut to database program
Set MyShortcut = WSHShell.CreateShortcut(DesktopPath & "\I am a
shortcut.lnk")
with MyShortcut
.TargetPath = "C:\wherever\whatever.exe"
.WorkingDirectory = "C:\wherever"
.WindowStyle = 4
.IconLocation = "C:\wherever\whatever.exe, 0"
.Save
end with
' ------------------------------------------
[13/17] from: atruter:hih:au at: 15-Oct-2002 15:08
> a sample script file (sample.sh) could contain:
Nice
> then from rebol its a simple shell call using the ShellExecute API
specifying the name of the script to call.
Err, this lost me a bit. ;) Could you provide an example of a "simple shell
call using the ShellExecute API" ...
Regards,
Ashley
[14/17] from: james:mustard at: 15-Oct-2002 19:47
Ashley wrote:
> Err, this lost me a bit. ;) Could you provide an example of a "simple
shell
> call using the ShellExecute API" ...
Someone may need to correct bits of this as I only have the free version of
View/Core but according to my interpretation of the docs the following
should be correct.
;---------------------------------------------------
shell-lib: load/library shell32.dll
ShellExecute: make routine! [
"this will execute an operation on a file"
hwnd [integer!] ; handle to the window of the calling app (for focus
issues) if you dont care use 0
lpOperation [string!] ; something like "OPEN" , "PRINT" , "EXPLORE" ,
FIND
etc.. depending on app.
lpFile [string!] ; file name (including path)
lpParameters [string!] ; if lpfile is an executable file you can add
parameters here
lpDirectory [string!] ; default directory
nShowCmd [integer!] ; one of the values shown below
] shell-lib "ShellExecuteA"
; options for the nShowCmd parameter (most people use 4 or 5)
SW_HIDE: 0 ; Hides the window and activates another window.
SW_SHOWNORMAL: 1 ; Activates and displays a window. If the window is
minimized or maximized, Windows restores it to its original size and
position. An application should specify this flag when displaying the window
for the first time.
SW_SHOWMINIMIZED: 2 ; Activates the window and displays it as a minimized
window.
SW_MAXIMIZE: 3 ; Maximizes the specified window.
SW_SHOWMAXIMIZED: 3 ; Activates the window and displays it as a maximized
window.
SW_SHOWNOACTIVATE: 4 ; Displays a window in its most recent size and
position. The active window remains active.
SW_SHOW: 5 ; Activates the window and displays it in its current size and
position.
SW_MINIMIZE: 6 ; Minimizes the specified window and activates the next
top-level window in the z-order.
SW_SHOWMINNOACTIVE: 7 ; Displays the window as a minimized window. The
active window remains active.
SW_SHOWNA: 8 ; Displays the window in its current state. The active window
remains active.
SW_RESTORE: 9 ; Activates and displays the window. If the window is
minimized or maximized, Windows restores it to its original size and
position. An application should specify this flag when restoring a minimized
window.
SW_SHOWDEFAULT: 10 ; Sets the show state based on the SW_ flag specified in
the STARTUPINFO structure passed to the CreateProcess function by the
program that started the application. An application should call ShowWindow
with this flag to set the initial show state of its main window.
; ----------------------------
; usage examples (I don't have /command or /pro to verify these but they
are correct according to the docs..)
;
; ShellExecute 0 "OPEN" "BananaEdit.exe" "a_new_doc.ban" "c:\" 5
;
; ShellExecute 0 "OPEN" "c:\my documents\status reports.doc" "" "c:\my
documents" 3
;
; ShellExecute 0 "PRINT" "c:\my documents\status reports.doc" "" "c:\my
documents" 0
;
; ShellExecute 0 "OPEN" "c:\shortcut.sh" "" "c:\" 4
;---------------------------------------------------------------------------
------------
James.
[15/17] from: greggirwin:mindspring at: 15-Oct-2002 9:21
Hi James, et al
You're spot on, except that you're routine! spec is missing the return
value.
shell-execute: make routine! [
hwndParent [integer!]
Operation [string!]
File [string!]
Parameters [string!]
Directory [string!]
ShowCmd [integer!]
return: [integer!]
] win-lib "ShellExecuteA"
--Gregg
[16/17] from: rebol665:ifrance at: 14-Oct-2002 8:38
Hi Gregg,
It works for me on Windows 2000 and on Windows 98.
Pat
----- Original Message -----
From: "Gregg Irwin" <[greggirwin--mindspring--com]>
To: <[rebol-list--rebol--com]>
Sent: Monday, October 14, 2002 1:07 AM
Subject: [REBOL] Re: Exploring System Port
> Hi All,
> OK, it looks like incoming Windows messages are formed like this:
<<quoted lines omitted: 59>>
> ]
> dropped-filename?: func [hdrop [integer!] index [integer!] /local
result
> len] [
> result: null-buff add 1 dropped-filename-size? hdrop index
<<quoted lines omitted: 29>>
> repeat i win-shell/num-files-dropped? msg/3 [
> file: to-rebol-file win-shell/dropped-filename? msg/3
i
> print [tab join i "." tab either dir? file [dirize
> file][file]]
<<quoted lines omitted: 24>>
> Etudiant: Wanadoo t'offre le Pack eXtense Haut Débit soit 150,92 euros
> d'économies ! Clique ici : http://www.ifrance.com/_reloc/mail.etudiant
______________________________________________________________________
Etudiant: Wanadoo t'offre le Pack eXtense Haut Débit soit 150,92 euros
d'économies ! Clique ici : http://www.ifrance.com/_reloc/mail.etudiant
[17/17] from: greggirwin:mindspring at: 20-Oct-2002 12:49
<< It works for me on Windows 2000 and on Windows 98. >>
Thanks Pat! I haven't been able to get it working on a View window yet, but
that's the next goal.
--Gregg
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted