(* OCaml-Win32
 * win32_comboboxex.ml
 * Copyright (c) 2002-2004 by Harry Chomsky
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *)

open Win32_core

(********************************************************************)
(* User Interface: Windows User Experience: Windows Shell: SDK: Windows Controls: Individual Control Information: ComboBoxEx Controls *)

let wc_comboboxex = "ComboBoxEx32"

type comboboxex_extended_style =
    CBES_EX_CASESENSITIVE
  | CBES_EX_NOEDITIMAGE
  | CBES_EX_NOEDITIMAGEINDENT
  | CBES_EX_NOSIZELIMIT
  | CBES_EX_PATHWORDBREAKPROC

type comboboxexitem = {
    cbei_item : int;
    cbei_text : common_control_text option;
    cbei_image : common_control_image_index option;
    cbei_selected_image : common_control_image_index option;
    cbei_overlay : common_control_image_index option;
    cbei_indent : common_control_indent_amount option;
    cbei_lparam : int32 option }
let default_comboboxexitem = {
    cbei_item = -1;
    cbei_text = None;
    cbei_image = None;
    cbei_selected_image = None;
    cbei_overlay = None;
    cbei_indent = None;
    cbei_lparam = None }

type comboboxexitem_component =
    Cbeif_text of int
  | Cbeif_image
  | Cbeif_selectedimage
  | Cbeif_overlay
  | Cbeif_indent
  | Cbeif_lparam
let all_comboboxexitem_components = [
    Cbeif_text 256;
    Cbeif_image;
    Cbeif_selectedimage;
    Cbeif_overlay;
    Cbeif_indent;
    Cbeif_lparam ]

(* Messages *)

let cbem_deleteitem = 0x0144
external pack_cbem_deleteitem : item:int -> message_contents = "pack_cbem_deleteitem"
external unpack_cbem_deleteitem : message_result -> int = "unpack_cbem_deleteitem"
let issue_cbem_deleteitem ~sender ~item = unpack_cbem_deleteitem (sender ~msg:(pack_cbem_deleteitem ~item))

let cbem_getcombocontrol = wm_user + 6
let pack_cbem_getcombocontrol = pack_simple_message ~id:cbem_getcombocontrol
external unpack_cbem_getcombocontrol : message_result -> hwnd = "unpack_cbem_getcombocontrol"
let issue_cbem_getcombocontrol ~sender = unpack_cbem_getcombocontrol (sender ~msg:pack_cbem_getcombocontrol)

let cbem_geteditcontrol = wm_user + 7
let pack_cbem_geteditcontrol = pack_simple_message ~id:cbem_geteditcontrol
external unpack_cbem_geteditcontrol : message_result -> hwnd = "unpack_cbem_geteditcontrol"
let issue_cbem_geteditcontrol ~sender = unpack_cbem_geteditcontrol (sender ~msg:pack_cbem_geteditcontrol)

let cbem_getextendedstyle = wm_user + 9
let pack_cbem_getextendedstyle = pack_simple_message ~id:cbem_getextendedstyle
external unpack_cbem_getextendedstyle : message_result -> comboboxex_extended_style list = "unpack_cbem_getextendedstyle"
let issue_cbem_getextendedstyle ~sender = unpack_cbem_getextendedstyle (sender ~msg:pack_cbem_getextendedstyle)

let cbem_getimagelist = wm_user + 3
let pack_cbem_getimagelist = pack_simple_message ~id:cbem_getimagelist
external unpack_cbem_getimagelist : message_result -> himagelist = "unpack_cbem_getimagelist"
let issue_cbem_getimagelist ~sender = unpack_cbem_getimagelist (sender ~msg:pack_cbem_getimagelist)

let cbem_getitem = wm_user + 4
external issue_cbem_getitem : sender:message_sender -> item:int -> mask:comboboxexitem_component list -> comboboxexitem = "issue_cbem_getitem"

(* cbem_getunicodeformat: use ccm_getunicodeformat *)

let cbem_haseditchanged = wm_user + 10
let pack_cbem_haseditchanged = pack_simple_message ~id:cbem_haseditchanged
external unpack_cbem_haseditchanged : message_result -> bool = "unpack_cbem_haseditchanged"
let issue_cbem_haseditchanged ~sender = unpack_cbem_haseditchanged (sender ~msg:pack_cbem_haseditchanged)

let cbem_insertitem = wm_user + 1
external issue_cbem_insertitem : sender:message_sender -> comboboxexitem:comboboxexitem -> int = "issue_cbem_insertitem"

let cbem_setextendedstyle = wm_user + 14
external pack_cbem_setextendedstyle :
    mask:comboboxex_extended_style list ->
    style:comboboxex_extended_style list ->
    message_contents = "pack_cbem_setextendedstyle"
external unpack_cbem_setextendedstyle : message_result -> comboboxex_extended_style list = "unpack_cbem_setextendedstyle"
let issue_cbem_setextendedstyle ~sender ~mask ~style = unpack_cbem_setextendedstyle (sender ~msg:(pack_cbem_setextendedstyle ~mask ~style))

let cbem_setimagelist = wm_user + 2
external pack_cbem_setimagelist : iml:himagelist -> message_contents = "pack_cbem_setimagelist"
external unpack_cbem_setimagelist : message_result -> himagelist = "unpack_cbem_setimagelist"
let issue_cbem_setimagelist ~sender ~iml = unpack_cbem_setimagelist (sender ~msg:(pack_cbem_setimagelist ~iml))

let cbem_setitem = wm_user + 5
external issue_cbem_setitem : sender:message_sender -> comboboxexitem:comboboxexitem -> unit = "issue_cbem_setitem"

(* cbem_setunicodeformat: use ccm_setunicodeformat *)

(* Notifications *)

type nmcomboboxex = {
    nmcbe_item : comboboxexitem }
external unpack_nmcomboboxex : msg:message_contents -> nmcomboboxex = "unpack_nmcomboboxex"

type nmcbedragbegin = {
    nmcbedb_item_id : int;
    nmcbedb_text : string }
external unpack_nmcbedragbegin : msg:message_contents -> nmcbedragbegin = "unpack_nmcbedragbegin"

type comboboxex_end_edit_reason =
    CBENF_DROPDOWN
  | CBENF_ESCAPE
  | CBENF_KILLFOCUS
  | CBENF_RETURN
type nmcbeendedit = {
    nmcbeee_changed : bool;
    nmcbeee_new_selection : int option;
    nmcbeee_text : string;
    nmcbeee_why : comboboxex_end_edit_reason }
external unpack_nmcbeendedit : msg:message_contents -> nmcbeendedit = "unpack_nmcbeendedit"

let cben_first = -800
let cben_last = -830

let cben_beginedit = cben_first - 4
let on_cben_beginedit = on_notify_message ~code:cben_beginedit ~unpack:unpack_simple_notify ~return:return_simple_message

let cben_deleteitem = cben_first - 2
let on_cben_deleteitem = on_notify_message ~code:cben_deleteitem ~unpack:unpack_nmcomboboxex ~return:return_simple_message

let cben_dragbegin = cben_first - 8
let on_cben_dragbegin = on_notify_message ~code:cben_dragbegin ~unpack:unpack_nmcbedragbegin ~return:return_simple_message

let cben_endedit = cben_first - 5
let on_cben_endedit = on_notify_message ~code:cben_endedit ~unpack:unpack_nmcbeendedit ~return:return_common_notify

let cben_getdispinfo = cben_first - 0
type cben_getdispinfo_handler =
    wnd:hwnd ->
    msg:message_contents ->
    id:int ->
    hdr:nmhdr ->
    item:int ->
    mask:comboboxexitem_component list ->
    (comboboxexitem * bool) message_handler_result
external on_cben_getdispinfo :
    cben_getdispinfo_handler ->
    wnd:hwnd ->
    msg:message_contents ->
    message_result option = "on_cben_getdispinfo"

let cben_insertitem = cben_first - 1
let on_cben_insertitem = on_notify_message ~code:cben_insertitem ~unpack:unpack_nmcomboboxex ~return:return_simple_message
