+/* instantiate a tree view widget */
+static HTREEITEM add_tree_item (Lisp_Object image_instance,
+ HWND wnd, HTREEITEM parent, Lisp_Object item,
+ int children, Lisp_Object domain)
+{
+ TV_INSERTSTRUCT tvitem;
+ HTREEITEM ret;
+
+ tvitem.hParent = parent;
+ tvitem.hInsertAfter = TVI_LAST;
+ tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
+ tvitem.item.cChildren = children;
+
+ if (GUI_ITEMP (item))
+ {
+ tvitem.item.lParam = mswindows_register_gui_item (item, domain);
+ tvitem.item.mask |= TVIF_PARAM;
+ GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name,
+ tvitem.item.pszText);
+ }
+ else
+ GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.item.pszText);
+
+ tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
+
+ if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
+ 0, (LPARAM)&tvitem)) == 0)
+ signal_simple_error ("error adding tree view entry", item);
+
+ return ret;
+}
+
+static void add_tree_item_list (Lisp_Object image_instance,
+ HWND wnd, HTREEITEM parent, Lisp_Object list,
+ Lisp_Object domain)
+{
+ Lisp_Object rest;
+
+ /* get the first item */
+ parent = add_tree_item (image_instance, wnd, parent, XCAR (list), TRUE, domain);
+ /* recursively add items to the tree view */
+ LIST_LOOP (rest, XCDR (list))
+ {
+ if (LISTP (XCAR (rest)))
+ add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
+ else
+ add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
+ }
+}
+
+static void
+mswindows_tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
+{
+ Lisp_Object rest;
+ HWND wnd;
+ HTREEITEM parent;
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, WC_TREEVIEW,
+ WS_TABSTOP | WS_BORDER | PBS_SMOOTH
+ | TVS_HASLINES | TVS_HASBUTTONS,
+ WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
+
+ wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+
+ /* define a root */
+ parent = add_tree_item (image_instance, wnd, NULL,
+ XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
+ TRUE, domain);
+
+ /* recursively add items to the tree view */
+ /* add items to the tab */
+ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
+ {
+ if (LISTP (XCAR (rest)))
+ add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
+ else
+ add_tree_item (image_instance, wnd, parent, XCAR (rest), FALSE, domain);
+ }
+}
+
+/* instantiate a tab control */
+static TC_ITEM* add_tab_item (Lisp_Object image_instance,
+ HWND wnd, Lisp_Object item,
+ Lisp_Object domain, int index)
+{
+ TC_ITEM tvitem, *ret;
+
+ tvitem.mask = TCIF_TEXT;
+
+ if (GUI_ITEMP (item))
+ {
+ tvitem.lParam = mswindows_register_gui_item (item, domain);
+ tvitem.mask |= TCIF_PARAM;
+ GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name,
+ tvitem.pszText);
+ }
+ else
+ {
+ CHECK_STRING (item);
+ GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.pszText);
+ }
+
+ tvitem.cchTextMax = strlen (tvitem.pszText);
+
+ if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM,
+ index, (LPARAM)&tvitem)) < 0)
+ signal_simple_error ("error adding tab entry", item);
+
+ return ret;
+}
+
+static void
+mswindows_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
+{
+ Lisp_Object rest;
+ HWND wnd;
+ int index = 0;
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, WC_TABCONTROL,
+ /* borders don't suit tabs so well */
+ WS_TABSTOP,
+ WS_EX_CONTROLPARENT);
+
+ wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ /* add items to the tab */
+ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
+ {
+ add_tab_item (image_instance, wnd, XCAR (rest), domain, index);
+ index++;
+ }
+}
+
+/* set the properties of a tab control */
+static Lisp_Object
+mswindows_tab_control_set_property (Lisp_Object image_instance, Lisp_Object prop,
+ Lisp_Object val)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+ if (EQ (prop, Q_items))
+ {
+ HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ int index = 0;
+ Lisp_Object rest;
+ check_valid_item_list_1 (val);
+
+ /* delete the pre-existing items */
+ SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
+
+ IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
+ Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
+ parse_gui_item_tree_children (val));
+
+ /* add items to the tab */
+ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
+ {
+ add_tab_item (image_instance, wnd, XCAR (rest),
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), index);
+ index++;
+ }
+
+ return Qt;
+ }
+ return Qunbound;
+}
+
+/* instantiate a static control possible for putting other things in */
+static void
+mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
+{
+ mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "STATIC",
+ 0, WS_EX_STATICEDGE);
+}
+
+/* instantiate a scrollbar control */
+static void
+mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
+{
+ mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "SCROLLBAR",
+ 0,
+ WS_EX_CLIENTEDGE );
+}
+
+/* instantiate a combo control */
+static void
+mswindows_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ HANDLE wnd;
+ Lisp_Object rest;
+ Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
+ Q_items, Qnil);
+ int len;
+ GET_LIST_LENGTH (data, len);
+
+ /* Maybe ought to generalise this more but it may be very windows
+ specific. In windows the window height of a combo box is the
+ height when the combo box is open. Thus we need to set the height
+ before creating the window and then reset it to a single line
+ after the window is created so that redisplay does the right
+ thing. */
+ widget_instantiate_1 (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, len + 1, 0, 0);
+
+ mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "COMBOBOX",
+ WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
+ | CBS_AUTOHSCROLL
+ | CBS_HASSTRINGS | WS_VSCROLL,
+ WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
+ /* reset the height */
+ widget_text_to_pixel_conversion (domain,
+ IMAGE_INSTANCE_WIDGET_FACE (ii), 1, 0,
+ &IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii), 0);
+ wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ /* add items to the combo box */
+ SendMessage (wnd, CB_RESETCONTENT, 0, 0);
+ LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
+ {
+ Extbyte* lparam;
+ GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam);
+ if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
+ signal_simple_error ("error adding combo entries", instantiator);
+ }
+}
+
+/* get properties of a control */
+static Lisp_Object
+mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ /* get the text from a control */
+ if (EQ (prop, Q_text))
+ {
+ Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
+ Extbyte* buf =alloca (len+1);
+
+ SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
+ return build_ext_string (buf, FORMAT_OS);
+ }
+ return Qunbound;
+}
+
+/* get properties of a button */
+static Lisp_Object
+mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ /* check the state of a button */
+ if (EQ (prop, Q_selected))
+ {
+ if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
+ return Qt;
+ else
+ return Qnil;
+ }
+ return Qunbound;
+}
+
+/* get properties of a combo box */
+static Lisp_Object
+mswindows_combo_box_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+ /* get the text from a control */
+ if (EQ (prop, Q_text))
+ {
+ long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
+ Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
+ Extbyte* buf = alloca (len+1);
+ SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
+ return build_ext_string (buf, FORMAT_OS);
+ }
+ return Qunbound;
+}
+
+/* set the properties of a control */
+static Lisp_Object
+mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
+ Lisp_Object val)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+ if (EQ (prop, Q_text))
+ {
+ Extbyte* lparam=0;
+ CHECK_STRING (val);
+ GET_C_STRING_OS_DATA_ALLOCA (val, lparam);
+ SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+ WM_SETTEXT, 0, (LPARAM)lparam);
+ return Qt;
+ }
+ return Qunbound;
+}
+
+/* set the properties of a progres guage */
+static Lisp_Object
+mswindows_progress_gauge_set_property (Lisp_Object image_instance, Lisp_Object prop,
+ Lisp_Object val)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+ if (EQ (prop, Q_percent))
+ {
+ CHECK_INT (val);
+ SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+ PBM_SETPOS, (WPARAM)XINT (val), 0);
+ return Qt;
+ }
+ return Qunbound;
+}
+
+LRESULT WINAPI
+mswindows_control_wnd_proc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_NOTIFY:
+ case WM_COMMAND:
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORSTATIC:
+ case WM_CTLCOLORSCROLLBAR:
+
+ return mswindows_wnd_proc (GetParent (hwnd), message, wParam, lParam);
+ default:
+ return DefWindowProc (hwnd, message, wParam, lParam);
+ }
+}
+
+#endif /* HAVE_WIDGETS */
+