I want to define a macro which encapsulates the frequent pattern below. The code is for FLI of lispworks.
(fli:with-foreign-string ;; class name pointer
(cn-p ec bc :external-format (external-format)) "BUTTON"
(fli:with-foreign-string ;; window name pointer
(wn-p ec bc :external-format (external-format)) "Configuartion:server"
(let ((grpbx (createwindowex 0 cn-p wn-p
(logior ws_visible ws_child bs_groupbox)
0 0 300 420 hwnd 1 (GetModuleHandle-current 0) 0)))
(fli:with-foreign-string ;; class name pointer
(cn-p ec bc :external-format (external-format)) "EDIT"
(fli:with-foreign-string ;; window name pointer
(wn-p ec bc :external-format (external-format)) "192.168.200.200"
(createwindowex 0 cn-p wn-p
(logior ws_visible ws_child ws_border)
10 30 150 30 hwnd 1 (GetModuleHandle-current 0) 0)
)))))
The macro I want to create is something like below: THe strs parameter is a list of strings, e.g. ("BUTTON" "Configuartion:server") above, str-syms accumulates the converted strings which will be fed to createwindowex. What confused me was that the strings to be used (cn-p and wn-p) are in the middle of the body, and I had to split the body into 2 parts: part-bdy and &body bdy.
But the problem is part-bdy, which is first part of LET block (before createwindowex), has many parentheses, whose counter parts are only in the send part (&body bdy). Which means the parentheses in part-bdy are not open and cause error when evaluated. Do you have any clever idea to advise me to solve it?
(defmacro with-foreign-string (strs str-syms part-bdy &body bdy)
(let ((g (gensym)))
(if (null strs)
(append part-bdy str-syms bdy)
`(fli:with-foreign-string
(,g ec bc :external-format (external-format)) ,(car strs)
(with-foreign-string ,(cdr strs) ,(cons g str-syms) ,part-bdy ,@bdy)))))
Just want to share that I changed the macro as below:
then the code code above without using the macro can be rewritten like this:
This is still not so clean but anyway I can manage to simplify the code using macro. There were not so many responses only because I think due to the FLI and win32 API in the code.