Is this newLISP's bug?

Started by psilwen, August 11, 2017, 05:50:30 AM

Previous topic - Next topic

psilwen

I created an edit window using following code:


(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)
(define WS_OVERLAPPEDWINDOW 0xCF0000)

; 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))
(CreateWindowExA
0
"Edit"
""
(| WS_VISIBLE WS_CHILD WS_VSCROLL ES_MULTILINE ES_AUTOVSCROLL)
50 50 (r 2) (r 3)
hWnd
IDC_TEXTBOX
hInstance
0
))
)

(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)
(cond
((= 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
CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT           ; x y w h
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")

(exit)


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.

snapshot: http://upgrade99.byethost7.com/newlisp/normal.png">http://upgrade99.byethost7.com/newlisp/normal.png

demo: http://upgrade99.byethost7.com/newlisp/good.wmv">http://upgrade99.byethost7.com/newlisp/good.wmv



In the case that the edit window created from newlisp.

snapshots: http://upgrade99.byethost7.com/newlisp/hangs.png">http://upgrade99.byethost7.com/newlisp/hangs.png

demo: http://upgrade99.byethost7.com/newlisp/hangs.wmv">http://upgrade99.byethost7.com/newlisp/hangs.wmv



I found a link that describes the fault that is very similar to this. at https://bugs.chromium.org/p/chromium/issues/detail?id=402782">//https://bugs.chromium.org/p/chromium/issues/detail?id=402782
(reverse \"newlisp\")

CaveGuy

#1
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 ....

destroyed

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")

>
Bob the Caveguy aka Lord High Fixer.

Lutz

#2
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:



http://newlisp.nfshost.com/downloads/development/inprogress/">http://newlisp.nfshost.com/downloads/de ... nprogress/">http://newlisp.nfshost.com/downloads/development/inprogress/

Lutz

#3
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.

psilwen

#4
I found the reason for the problem!



The descriptions for the hWnd parameter of GetMessage:


QuoteA 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.
(reverse \"newlisp\")