[PATCH 1/2] twain_32: Implement source selection dialog.

Vincent Povirk vincent at codeweavers.com
Thu Nov 16 16:07:15 CST 2017


Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
---
 dlls/twain_32/Makefile.in    |   2 +
 dlls/twain_32/dsm_ctrl.c     | 114 ++++++++++++++++++++++++++++++++++++++-----
 dlls/twain_32/resource.h     |  25 ++++++++++
 dlls/twain_32/twain.rc       |  34 +++++++++++++
 dlls/twain_32/twain32_main.c |  18 +++++++
 dlls/twain_32/twain_i.h      |   2 +
 6 files changed, 182 insertions(+), 13 deletions(-)
 create mode 100644 dlls/twain_32/resource.h
 create mode 100644 dlls/twain_32/twain.rc

diff --git a/dlls/twain_32/Makefile.in b/dlls/twain_32/Makefile.in
index cadaf8081d8..c82b5a74453 100644
--- a/dlls/twain_32/Makefile.in
+++ b/dlls/twain_32/Makefile.in
@@ -4,3 +4,5 @@ IMPORTS   = user32
 C_SRCS = \
 	dsm_ctrl.c \
 	twain32_main.c
+
+RC_SRCS = twain.rc
diff --git a/dlls/twain_32/dsm_ctrl.c b/dlls/twain_32/dsm_ctrl.c
index 9b878676656..bfd0651cb46 100644
--- a/dlls/twain_32/dsm_ctrl.c
+++ b/dlls/twain_32/dsm_ctrl.c
@@ -30,6 +30,7 @@
 #include "winuser.h"
 #include "twain.h"
 #include "twain_i.h"
+#include "resource.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(twain);
@@ -345,24 +346,111 @@ TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
 	return TWRC_SUCCESS;
 }
 
+typedef struct {
+    pTW_IDENTITY origin;
+    pTW_IDENTITY result;
+} userselect_data;
+
+INT_PTR CALLBACK userselect_dlgproc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    switch (msg)
+    {
+    case WM_INITDIALOG:
+    {
+        userselect_data *data = (userselect_data*)lparam;
+        int i;
+        HWND sourcelist;
+        BOOL any_devices = FALSE;
+
+        SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)data);
+
+        sourcelist = GetDlgItem(hwnd, IDC_LISTSOURCE);
+
+        for (i=0; i<nrdevices; i++)
+        {
+            TW_IDENTITY *id = &devices[i].identity;
+            LRESULT index;
+
+            if ((id->SupportedGroups & data->origin->SupportedGroups) == 0)
+                continue;
+
+            index = SendMessageA(sourcelist, LB_ADDSTRING, 0, (LPARAM)id->ProductName);
+            SendMessageW(sourcelist, LB_SETITEMDATA, (WPARAM)index, (LPARAM)i);
+            any_devices = TRUE;
+        }
+
+        if (any_devices)
+        {
+            EnableWindow(GetDlgItem(hwnd, IDOK), TRUE);
+
+            /* FIXME: Select the supplied product name or default source. */
+            SendMessageW(sourcelist, LB_SETCURSEL, 0, 0);
+        }
+
+        return TRUE;
+    }
+    case WM_CLOSE:
+        EndDialog(hwnd, 0);
+        return TRUE;
+    case WM_COMMAND:
+        if (wparam == MAKEWPARAM(IDCANCEL, BN_CLICKED))
+        {
+            EndDialog(hwnd, 0);
+            return TRUE;
+        }
+        else if (wparam == MAKEWPARAM(IDOK, BN_CLICKED) ||
+                 wparam == MAKEWPARAM(IDC_LISTSOURCE, LBN_DBLCLK))
+        {
+            userselect_data *data = (userselect_data*)GetWindowLongPtrW(hwnd, DWLP_USER);
+            HWND sourcelist;
+            LRESULT index;
+
+            sourcelist = GetDlgItem(hwnd, IDC_LISTSOURCE);
+
+            index = SendMessageW(sourcelist, LB_GETCURSEL, 0, 0);
+
+            if (index == LB_ERR)
+                return TRUE;
+
+            index = SendMessageW(sourcelist, LB_GETITEMDATA, (WPARAM)index, 0);
+
+            *data->result = devices[index].identity;
+
+            /* FIXME: Save this as the default source */
+
+            EndDialog(hwnd, 1);
+            return TRUE;
+        }
+        break;
+    }
+    return FALSE;
+}
+
 /* DG_CONTROL/DAT_IDENTITY/MSG_USERSELECT */
 TW_UINT16 TWAIN_UserSelect (pTW_IDENTITY pOrigin, TW_MEMREF pData)
 {
-	pTW_IDENTITY	selected = (pTW_IDENTITY)pData;
+    userselect_data param = {pOrigin, pData};
+    HWND parent = DSM_parent;
 
-        TRACE("DG_CONTROL/DAT_IDENTITY/MSG_USERSELECT SupportedGroups=0x%x ProductName=%s\n",
-            selected->SupportedGroups, wine_dbgstr_a(selected->ProductName));
+    TRACE("DG_CONTROL/DAT_IDENTITY/MSG_USERSELECT SupportedGroups=0x%x ProductName=%s\n",
+        pOrigin->SupportedGroups, wine_dbgstr_a(param.result->ProductName));
 
-        twain_autodetect();
-	if (!nrdevices) {
-                TRACE("<-- TWRC_FAILURE\n");
-		DSM_twCC = TWCC_OPERATIONERROR;
-		return TWRC_FAILURE;
-	}
-	*selected = devices[0].identity;
-        TRACE("<-- %s\n", wine_dbgstr_a(selected->ProductName));
-	DSM_twCC = TWCC_SUCCESS;
-	return TWRC_SUCCESS;
+    twain_autodetect();
+
+    if (!IsWindow(parent))
+        parent = NULL;
+
+    if (DialogBoxParamW(DSM_hinstance, MAKEINTRESOURCEW(DLG_USERSELECT),
+        parent, userselect_dlgproc, (LPARAM)&param) == 0)
+    {
+        TRACE("canceled\n");
+        DSM_twCC = TWCC_SUCCESS;
+        return TWRC_CANCEL;
+    }
+
+    TRACE("<-- %s\n", wine_dbgstr_a(param.result->ProductName));
+    DSM_twCC = TWCC_SUCCESS;
+    return TWRC_SUCCESS;
 }
 
 /* DG_CONTROL/DAT_PARENT/MSG_CLOSEDSM */
diff --git a/dlls/twain_32/resource.h b/dlls/twain_32/resource.h
new file mode 100644
index 00000000000..366f52f181c
--- /dev/null
+++ b/dlls/twain_32/resource.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017 Vincent Povirk for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windef.h>
+#include <winuser.h>
+
+#define DLG_USERSELECT 1
+
+#define IDC_LISTSOURCE 1001
+
diff --git a/dlls/twain_32/twain.rc b/dlls/twain_32/twain.rc
new file mode 100644
index 00000000000..2c5939308d5
--- /dev/null
+++ b/dlls/twain_32/twain.rc
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017 Vincent Povirk for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "resource.h"
+
+#pragma makedep po
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+DLG_USERSELECT DIALOG  0, 0, 140, 140
+STYLE DS_MODALFRAME | DS_3DLOOK | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_POPUP | DS_NOIDLEMSG
+FONT 8, "MS Shell Dlg"
+CAPTION "Select Source"
+{
+    LISTBOX         IDC_LISTSOURCE,      7,     7,  126, 104
+    DEFPUSHBUTTON   "OK",     IDOK,      29,  118,  50,  15,  BS_DEFPUSHBUTTON|WS_TABSTOP|WS_DISABLED
+    PUSHBUTTON      "Cancel", IDCANCEL,  83,  118,  50,  15
+}
+
diff --git a/dlls/twain_32/twain32_main.c b/dlls/twain_32/twain32_main.c
index d1977b4d75f..016680b96eb 100644
--- a/dlls/twain_32/twain32_main.c
+++ b/dlls/twain_32/twain32_main.c
@@ -31,6 +31,24 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(twain);
 
+extern HINSTANCE DSM_hinstance;
+
+BOOL WINAPI DllMain (HINSTANCE hinstance, DWORD reason, LPVOID reserved)
+{
+    TRACE("%p,%x,%p\n", hinstance, reason, reserved);
+
+    switch (reason)
+    {
+        case DLL_PROCESS_ATTACH:
+            DisableThreadLibraryCalls(hinstance);
+            DSM_hinstance = hinstance;
+            break;
+        case DLL_PROCESS_DETACH:
+            break;
+    }
+    return TRUE;
+}
+
 /* A helper function that looks up a destination identity in the active
    source list */
 static activeDS *TWAIN_LookupSource (const TW_IDENTITY *pDest)
diff --git a/dlls/twain_32/twain_i.h b/dlls/twain_32/twain_i.h
index f46999c6fa1..4d33135344e 100644
--- a/dlls/twain_32/twain_i.h
+++ b/dlls/twain_32/twain_i.h
@@ -53,6 +53,8 @@ TW_UINT16 DSM_twCC DECLSPEC_HIDDEN;             /* current condition code of Sou
 
 activeDS *activeSources DECLSPEC_HIDDEN;	/* list of active data sources */
 
+HINSTANCE DSM_hinstance DECLSPEC_HIDDEN;
+
 /* Implementation of operation triplets (From Application to Source Manager) */
 extern TW_UINT16 TWAIN_CloseDS
            (pTW_IDENTITY pOrigin, TW_MEMREF pData) DECLSPEC_HIDDEN;
-- 
2.11.0




More information about the wine-devel mailing list