Page 1 of 1

Is this newLISP's bug?

PostPosted: Fri Aug 11, 2017 12:50 pm
by psilwen
I created an edit window using following code:

Code: Select all
(define (import-list library flist)
    (dolist (fname flist) (import library (string fname))))

(define-macro (@setq %var %value)
    (set %var (eval %value))
    (println %var " " (eval %var)))

; Constants
(define IDC_TEXTBOX   1000)
(define IDC_ARROW 0x7F00)
(define COLOR_WINDOW 5)

; Window Messages
(define WM_CREATE  1)
(define WM_DESTROY 2)
(define WM_SIZE    5)

; Window Styles
(define WS_CHILD            0x40000000)
(define WS_VISIBLE          0x10000000)
(define WS_VSCROLL          0x00200000)

; Class styles
(define CS_VREDRAW          0x0001)
(define CS_HREDRAW          0x0002)

; ShowWindow constant
(define SW_SHOWDEFAULT 10)
(define SW_HIDE 0)
(define SW_SHOW 5)

; Edit control
(define ES_MULTILINE        0x0004)
(define ES_AUTOVSCROLL      0x0040)

; CreateWindowEx
(define CW_USEDEFAULT       0x80000000)

(import-list "kernel32" '(GetModuleHandleA))
(import-list "user32" '(PostQuitMessage DefWindowProcA))
(import-list "user32" '(RegisterClassA CreateWindowExA))
(import-list "user32" '(ShowWindow UpdateWindow MoveWindow DestroyWindow))
(import-list "user32" '(GetMessageA TranslateMessage DispatchMessageA))
(import-list "user32" '(LoadCursorA GetClientRect))

(@setq hInstance (GetModuleHandleA 0))
(@setq hTextbox nil)
(@setq hCursor (LoadCursorA 0 IDC_ARROW))

(struct 'RECT "long" "long" "long" "long")

(define (CreateTextBox hWnd)
   (let (r (pack RECT))
      (GetClientRect hWnd r)
      (setq r (unpack RECT r))
         50 50 (r 2) (r 3)

(define (OnCreate hwnd wparam lparam)
   (setq hTextbox (CreateTextBox hwnd))
(define (OnSize hwnd wparam lparam)
    (let (rc (pack RECT))
       (GetClientRect hwnd rc)
       (setq rc (unpack RECT rc))
       (MoveWindow hTextbox (rc 0) (rc 1) (rc 2) (rc 3) 1)

(define (OnDestroy)
   (println "destroyed")
   (PostQuitMessage 0)

(define (window-callback-function hwnd message wparam lparam)
      ((= message WM_CREATE)      (OnCreate hwnd wparam lparam) 0)
      ((= message WM_SIZE)        (OnSize hwnd wparam lparam)   0)
      ((= message WM_DESTROY)     (OnDestroy)                   0)
      (true (DefWindowProcA hwnd message wparam lparam))))

(setq wndproc (callback 0 'window-callback-function))
(setq classname "newlisp class")

(setq wc (pack (dup "ld" 10)
         (| CS_HREDRAW CS_VREDRAW)   ; style
         wndproc                     ; lpfnWndProc
         0                           ; cbClsExtra
         0                           ; cbWndExtra
         hInstance                   ; hInstance
         0                           ; hIcon
         hCursor                     ; hCursor
         (+ COLOR_WINDOW 1)          ; hbrBackground
         0                           ; lpszMenuName
         classname                   ; lpszClassName

(@setq hwc (RegisterClassA wc))
(@setq hwnd (CreateWindowExA
            0                       ; dwExStyle
            "newlisp class"         ; lpClassName
            "newlisp Edit Control Test"        ; lpWindowName
            WS_OVERLAPPEDWINDOW     ; dwStyle
            0                       ; hwndParent
            0                       ; hMenu
            hInstance               ; hInstance
            0                       ; hParam

(ShowWindow hwnd SW_SHOWDEFAULT)
(UpdateWindow hwnd)

(setq msg (pack "n28"))

(until (member (GetMessageA msg hwnd 0 0) '(0 -1))
   (TranslateMessage msg)
   (DispatchMessageA msg))

(println "the end")


It's no probrem when typing english text, but when i press CTRL + SPACE switch to Chinese IME, and typing something,
appears three window: a IME status bar at bottom left corner of the screen, a small IME input window and an IME candidate window that following the caret.

The small IME input window and the IME status bar is blank. (It's not the right situation)

The candidate window shows what it should display, but when i choose one from the candidate list by clicked it, it's caused newlisp hangs.

In addition, you can not use CTRL + SHIFT to switch between different input methods.

My test environment is Windows 7 Ultimate 64 bit.

It's also has this issues on Windows XP SP3 32bit.

I guess this problem also exists in the Japanese IME case.

I captured the picture and recorded to video, hoping to describe the problem clearly.

The behaviors of edit window with IME, in normal case.

In the case that the edit window created from newlisp.

I found a link that describes the fault that is very similar to this. at

Re: Is this newLISP's bug?

PostPosted: Fri Aug 11, 2017 3:29 pm
by CaveGuy
not sure if this helps but I am working with the same example and get a lockup with an unhandled win32 exception [10892] when I run it in 64bit newlisp but it runs as expected in 32 bit newlisp.

newLISP v.10.7.1 64-bit on Windows IPv4/6 UTF-8 libffi, options: newlisp -h

> (load "w32test2.lsp")
hInstance 4194304
hTextbox nil
hCursor 65539
> window never opens - newlisp aborts with a dialog box

newLISP v.10.7.1 32-bit on Windows IPv4/6 UTF-8 libffi, options: newlisp -h

> (load "w32test2.lsp")
hInstance 4194304
hTextbox nil
hCursor 65539
hwc 50081
hwnd 2294990
> window opens and I can type in it ....
the end
exits normally

just tested
newLISP v.10.7.3 64-bit on Windows IPv4/6 libffi, options: newlisp -h
it exits with the same debugger error.
I am on windows 10 and do not have visual studio thus the debugger info is useless to me.

here is a new twist ...

newLISP v.10.7.3 32-bit on Windows IPv4/6, options: newlisp -h

> (load "w32test2.lsp")
hInstance 4194304
hTextbox nil
hCursor 65539

ERR: invalid function : (struct 'RECT "long" "long" "long" "long")

Re: Is this newLISP's bug?

PostPosted: Fri Aug 11, 2017 4:02 pm
by Lutz
The funtion 'struct' is only available on the extended ffi enabled versions. The 32-bit version was compiled without it. Here update 32-bit with ffi: ... nprogress/

Re: Is this newLISP's bug?

PostPosted: Fri Aug 11, 2017 4:17 pm
by Lutz
Also note, that 'struct' take C-language struct types. "long" on the 32-bit version of newLISP is 32-bit wide but 64-bit wide on the 64-bit version of newLISP. To specify a 32-bit wide signed data type specify "int" which will be 32-bit on both versions of newLISP, or "long long" which will be 64-bit on both versions of newLISP.

Re: Is this newLISP's bug?

PostPosted: Mon Aug 14, 2017 4:41 pm
by psilwen
I found the reason for the problem!

The descriptions for the hWnd parameter of GetMessage:

A handle to the window whose messages are to be retrieved. The window must belong to the current thread.
If hWnd is NULL, GetMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL. Therefore if hWnd is NULL, both window messages and thread messages are processed.

The IME window belong to the current thread, but it's messages doesn't retrieved and processed, so it's hangs!

So, just change hwnd to 0 on it. It will be able to work as expected.

(GetMessage msg hwnd 0 0) ==> (GetMessage msg 0 0 0)

Thanks everybody.