1

我想定义一个宏来封装下面的频繁模式。该代码适用于 lispworks 的 FLI。

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

我要创建的宏如下所示:strs参数是字符串列表,例如上面的("BUTTON" "Configuartion:server")str-syms会累积转换后的字符串,这些字符串将被馈送到createwindowex。让我困惑的是要使用的字符串(cn-p 和 wn-p)在 body 的中间,我不得不将 body 分成 2 部分:part-bdy&body bdy。

但问题是part-bdy,它是LET块的第一部分(在createwindowex之前),有很多括号,其对应部分仅在发送部分(&body bdy)。这意味着part-bdy中的括号未打开并在评估时导致错误。你有什么聪明的主意可以建议我解决吗?

(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)))))
4

1 回答 1

2

只是想分享一下我将宏更改如下:

(defmacro with-foreign-str (strs str-syms bdy)
    (if (null strs)
    bdy
      `(let ((,(car str-syms) (gensym)))
      (fli:with-foreign-string
    (,(car str-syms) ec bc :external-format (external-format)) ,(car strs)
    (with-foreign-str ,(cdr strs) ,(cdr str-syms) ,bdy)))))

那么上面不使用宏的代码代码可以这样重写:

  (WITH-FOREIGN-STR ("BUTTON" "Configuartion: server") (cn-p wn-p)
    (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)))
          (WITH-FOREIGN-STR ("EDIT" "192.168.200.95") (cn-p3 wn-p3) 
               (createwindowex 0 cn-p3 wn-p3
                               (logior ws_visible ws_child ws_border)
               10 30 150 30 hwnd 1 (GetModuleHandle-current 0) 0))))

这仍然不是那么干净,但无论如何我可以设法使用宏来简化代码。之所以没有这么多响应,只是因为我认为是由于代码中的 FLI 和 win32 API。

于 2017-01-10T08:08:44.650 回答