[racket] ffi->SendMessageTimeoutW

From: heraklea at gmx.de (heraklea at gmx.de)
Date: Fri Jan 18 09:45:27 EST 2013

Hello friends,

I try to access SendMessageTimeout throgh ffi.

I write:
[CODE_BEGIN]
#lang racket
(require ffi/com
         ffi/unsafe
         ffi/unsafe/define
         ffi/winapi
         racket/string
         racket/format)

(define _HKEY 	(_cpointer/null 'HKEY))
(define _HANDLE (_cpointer/null 'HANDLE))
(define _HWND 	(_cpointer/null 'HWND))
(define _HINSTANCE (_cpointer/null 'HINSTANCE))
(define _LONG       _long)
(define _WORD       _int16)
(define _DWORD      _int32)
(define _REGSAM     _DWORD)
(define _LONG_PTR   _intptr)
(define _LPARAM     _LONG_PTR)
(define _LRESULT    _LONG_PTR)
(define _HRESULT    _LONG)
(define _WPARAM     _intptr)
(define _UINT       _uint)
(define _BOOL       (make-ctype _int (lambda (v) (if v 1 0)) (lambda (v) (not (zero? v)))))

(define SMTO_ABORTIFHUNG        #x0002)
(define SMTO_BLOCK              #x0001)
(define SMTO_NORMAL             #x0000)
(define SMTO_NOTIMEOUTIFNOTHUNG #x0008)
(define SMTO_ERRORONEXIT        #x0020)


(define HWND_BROADCAST (cast #xffff _intptr _HWND))
(define WM_WININICHANGE         #x001A)
(define WM_SETTINGCHANGE        WM_WININICHANGE)

(define kernel-dll (and (eq? (system-type) 'windows)
                        (ffi-lib "Kernel32.dll")))

(define user32-dll (and (eq? (system-type) 'windows)
                        (ffi-lib "User32.dll")))
(define-ffi-definer define-kernel kernel-dll
  #:default-make-fail make-not-available)

(define-ffi-definer define-user32 user32-dll
  #:default-make-fail make-not-available)

(define-kernel GetLastError (_fun #:abi winapi
                                  -> (r : _DWORD)))


(define-user32 SendMessageTimeoutW (_fun #:abi winapi
                                      _HWND
                                      _UINT
                                      _WPARAM
                                      _LPARAM
                                      _UINT
                                      _UINT
                                      (lpdwResult : (_ptr o _DWORD))
                                      -> (r : _long)
                                      -> (values r lpdwResult )))
(define ENV (cast "Environment" _string/utf-16 _intptr))

[CODE_END]

In C++ I make this:
DWORD dwResult = 0;
LRESULT Return = 0;
Return = ::SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)TEXT("Environment"), SMTO_ABORTIFHUNG, 5000, &dwResult);

DWORD err = ::GetLastError();
Here I get 0 in err (Return =0 and dwResult = 1);

But in Racket when I call the function:

(define-values ( r4 res4) (SendMessageTimeoutW HWND_BROADCAST
                                               WM_SETTINGCHANGE
                                               0
                                               ENV
                                               SMTO_ABORTIFHUNG
                                               5000))
I get r4= 1 and res4=0
But (GetLastError) gives 3 and this means ERROR_PATH_NOT_FOUND.

Which path is here mentioned?
Is the ffi define correct, especially the way I define ENV gives me a headache?

Yours,

Posted on the users mailing list.