4 * Copyright 2006 CodeWeavers, Aric Stewart
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #define NONAMELESSUNION
28 #define NONAMELESSSTRUCT
37 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(twain);
45 #define ID_EDIT_BASE 0x1000
46 #define ID_STATIC_BASE 0x2000
48 static INT_PTR CALLBACK DialogProc (HWND , UINT , WPARAM , LPARAM );
49 static INT CALLBACK PropSheetProc(HWND, UINT,LPARAM);
51 static int create_leading_static(HDC hdc, LPCSTR text,
52 LPDLGITEMTEMPLATEW* template_out, int y, int id)
54 LPDLGITEMTEMPLATEW tpl = NULL;
65 base = GetDialogBaseUnits();
67 len = MultiByteToWideChar(CP_ACP,0,text,-1,NULL,0);
69 len += sizeof(DLGITEMTEMPLATE);
70 len += 3*sizeof(WORD);
72 tpl = HeapAlloc(GetProcessHeap(),0,len);
73 tpl->style=WS_VISIBLE;
74 tpl->dwExtendedStyle = 0;
79 GetTextExtentPoint32A(hdc,text,lstrlenA(text),&size);
81 tpl->cx = MulDiv(size.cx,4,LOWORD(base));
82 tpl->cy = MulDiv(size.cy,8,HIWORD(base)) * 2;
83 ptr = (LPBYTE)tpl + sizeof(DLGITEMTEMPLATE);
84 *(LPWORD)ptr = 0xffff;
86 *(LPWORD)ptr = 0x0082;
88 ptr += MultiByteToWideChar(CP_ACP,0,text,-1,(LPWSTR)ptr,len) * sizeof(WCHAR);
89 *(LPWORD)ptr = 0x0000;
95 static int create_trailing_edit(HDC hdc, LPDLGITEMTEMPLATEW* template_out, int id,
96 int y, LPCSTR text,BOOL is_int)
98 LPDLGITEMTEMPLATEW tpl = NULL;
103 static const char int_base[] = "0000 xxx";
104 static const char float_base[] = "0000.0000 xxx";
106 base = GetDialogBaseUnits();
108 len = MultiByteToWideChar(CP_ACP,0,text,-1,NULL,0);
109 len *= sizeof(WCHAR);
110 len += sizeof(DLGITEMTEMPLATE);
111 len += 3*sizeof(WORD);
113 tpl = HeapAlloc(GetProcessHeap(),0,len);
114 tpl->style=WS_VISIBLE|ES_READONLY|WS_BORDER;
115 tpl->dwExtendedStyle = 0;
121 GetTextExtentPoint32A(hdc,int_base,lstrlenA(int_base),&size);
123 GetTextExtentPoint32A(hdc,float_base,lstrlenA(float_base),&size);
125 tpl->cx = MulDiv(size.cx*2,4,LOWORD(base));
126 tpl->cy = MulDiv(size.cy,8,HIWORD(base)) * 2;
128 ptr = (LPBYTE)tpl + sizeof(DLGITEMTEMPLATE);
129 *(LPWORD)ptr = 0xffff;
131 *(LPWORD)ptr = 0x0081;
133 ptr += MultiByteToWideChar(CP_ACP,0,text,-1,(LPWSTR)ptr,len) * sizeof(WCHAR);
134 *(LPWORD)ptr = 0x0000;
141 static int create_item(activeDS *pSource,HDC hdc, const SANE_Option_Descriptor *opt,
142 INT id, LPDLGITEMTEMPLATEW *template_out, int y, int *cx, int* count)
144 LPDLGITEMTEMPLATEW tpl = NULL,rc = NULL;
146 DWORD styles = WS_VISIBLE;
148 LPDLGITEMTEMPLATEW lead_static = NULL;
149 LPDLGITEMTEMPLATEW trail_edit = NULL;
150 DWORD leading_len = 0;
162 GetTextExtentPoint32A(hdc,"X",1,&size);
163 base = GetDialogBaseUnits();
164 base_x = MulDiv(size.cx,4,LOWORD(base));
166 if (opt->type == SANE_TYPE_BOOL)
168 class = 0x0080; /* Button */
169 styles |= BS_AUTOCHECKBOX;
170 local_len += MultiByteToWideChar(CP_ACP,0,opt->title,-1,NULL,0);
171 local_len *= sizeof(WCHAR);
174 else if (opt->type == SANE_TYPE_INT)
178 sane_control_option(pSource->deviceHandle, id-ID_BASE,
179 SANE_ACTION_GET_VALUE, &i,NULL);
181 sprintf(buffer,"%i",i);
183 if (opt->constraint_type == SANE_CONSTRAINT_NONE)
185 class = 0x0081; /* Edit*/
188 local_len += MultiByteToWideChar(CP_ACP,0,title,-1,NULL,0);
189 local_len *= sizeof(WCHAR);
191 else if (opt->constraint_type == SANE_CONSTRAINT_RANGE)
193 class = 0x0084; /* scroll */
194 ctl_cx = 10 * base_x;
195 trail_len += create_trailing_edit(hdc, &trail_edit, id +
196 ID_EDIT_BASE, y,buffer,TRUE);
200 class= 0x0085; /* Combo */
201 ctl_cx = 10 * base_x;
202 styles |= CBS_DROPDOWNLIST;
204 leading_len += create_leading_static(hdc, opt->title, &lead_static, y,
207 else if (opt->type == SANE_TYPE_FIXED)
212 i = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));
214 sane_control_option(pSource->deviceHandle, id-ID_BASE,
215 SANE_ACTION_GET_VALUE, i, NULL);
218 sprintf(buffer,"%f",dd);
219 HeapFree(GetProcessHeap(),0,i);
221 if (opt->constraint_type == SANE_CONSTRAINT_NONE)
223 class = 0x0081; /* Edit */
225 local_len += MultiByteToWideChar(CP_ACP,0,title,-1,NULL,0);
226 local_len *= sizeof(WCHAR);
228 else if (opt->constraint_type == SANE_CONSTRAINT_RANGE)
230 class= 0x0084; /* scroll */
231 ctl_cx = 10 * base_x;
232 trail_len += create_trailing_edit(hdc, &trail_edit, id +
233 ID_EDIT_BASE, y,buffer,FALSE);
237 class= 0x0085; /* Combo */
238 ctl_cx = 10 * base_x;
239 styles |= CBS_DROPDOWNLIST;
241 leading_len += create_leading_static(hdc, opt->title, &lead_static, y,
244 else if (opt->type == SANE_TYPE_STRING)
246 if (opt->constraint_type == SANE_CONSTRAINT_NONE)
248 class = 0x0081; /* Edit*/
252 class= 0x0085; /* Combo */
253 ctl_cx = opt->size * base_x;
254 styles |= CBS_DROPDOWNLIST;
256 leading_len += create_leading_static(hdc, opt->title, &lead_static, y,
258 sane_control_option(pSource->deviceHandle, id-ID_BASE,
259 SANE_ACTION_GET_VALUE, buffer,NULL);
262 local_len += MultiByteToWideChar(CP_ACP,0,title,-1,NULL,0);
263 local_len *= sizeof(WCHAR);
265 else if (opt->type == SANE_TYPE_BUTTON)
267 class = 0x0080; /* Button */
268 local_len += MultiByteToWideChar(CP_ACP,0,opt->title,-1,NULL,0);
269 local_len *= sizeof(WCHAR);
272 else if (opt->type == SANE_TYPE_GROUP)
274 class = 0x0080; /* Button */
275 styles |= BS_GROUPBOX;
276 local_len += MultiByteToWideChar(CP_ACP,0,opt->title,-1,NULL,0);
277 local_len *= sizeof(WCHAR);
281 local_len += sizeof(DLGITEMTEMPLATE);
283 local_len += 3*sizeof(WORD);
285 local_len += 4*sizeof(WORD);
289 padding = leading_len % sizeof(DWORD);
290 rc = HeapReAlloc(GetProcessHeap(),0,lead_static,leading_len+local_len + padding);
291 tpl = (LPDLGITEMTEMPLATEW)((LPBYTE)rc + leading_len + padding);
294 rc = tpl = HeapAlloc(GetProcessHeap(),0,local_len);
297 tpl->dwExtendedStyle = 0;
299 tpl->x = lead_static->x + lead_static->cx + 1;
300 else if (opt->type == SANE_TYPE_GROUP)
309 GetTextExtentPoint32A(hdc,title,lstrlenA(title),&size);
316 tpl->cy = lead_static->cy;
325 ptr = (LPBYTE)tpl + sizeof(DLGITEMTEMPLATE);
326 *(LPWORD)ptr = 0xffff;
328 *(LPWORD)ptr = class;
332 ptr += MultiByteToWideChar(CP_ACP,0,title,-1,(LPWSTR)ptr,local_len) * sizeof(WCHAR);
336 *(LPWORD)ptr = 0x0000;
340 *((LPWORD)ptr) = 0x0000;
345 trail_edit->x = tpl->cx + tpl->x + 2;
346 *cx = trail_edit->x + trail_edit->cx;
348 padding2 = (leading_len + local_len + padding)% sizeof(DWORD);
350 rc = HeapReAlloc(GetProcessHeap(),0,rc,leading_len+local_len + padding
351 +padding2+trail_len);
353 memcpy(((LPBYTE)rc) + leading_len + local_len + padding + padding2,
354 trail_edit,trail_len);
357 *cx = tpl->cx + tpl->x;
368 return leading_len + local_len + padding + padding2 + trail_len;
372 static LPDLGTEMPLATEW create_options_page(HDC hdc, activeDS *pSource, int *from_index,
379 LPDLGTEMPLATEW tpl = NULL;
380 LPBYTE all_controls = NULL;
381 DWORD control_len = 0;
383 int group_max_cx = 0;
385 int group_offset = -1;
386 INT control_count = 0;
388 rc = sane_control_option(pSource->deviceHandle, 0, SANE_ACTION_GET_VALUE,
391 if (rc != SANE_STATUS_GOOD)
393 ERR("Unable to read number of options\n");
397 for (i = *from_index; i < optcount; i++)
399 LPDLGITEMTEMPLATEW item_tpl = NULL;
400 const SANE_Option_Descriptor *opt;
405 int hold_for_group = 0;
407 opt = sane_get_option_descriptor(pSource->deviceHandle, i);
408 if (opt->type == SANE_TYPE_GROUP && split_tabs)
422 len = create_item(pSource, hdc, opt, ID_BASE + i, &item_tpl, y, &x,
425 control_count += count;
433 y+= item_tpl->cy + 1;
434 max_cx = max(max_cx, x + 2);
435 group_max_cx = max(group_max_cx, x );
437 padding = len % sizeof(DWORD);
442 newone = HeapReAlloc(GetProcessHeap(),0,all_controls,
443 control_len + len + padding);
444 all_controls = newone;
445 memcpy(all_controls+control_len,item_tpl,len);
446 memset(all_controls+control_len+len,0xca,padding);
447 HeapFree(GetProcessHeap(),0,item_tpl);
453 all_controls = (LPBYTE)item_tpl;
457 all_controls = HeapAlloc(GetProcessHeap(),0,len + padding);
458 memcpy(all_controls,item_tpl,len);
459 memset(all_controls+len,0xcb,padding);
460 HeapFree(GetProcessHeap(),0,item_tpl);
464 if (opt->type == SANE_TYPE_GROUP)
466 if (group_offset == -1)
468 group_offset = control_len;
473 LPDLGITEMTEMPLATEW group =
474 (LPDLGITEMTEMPLATEW)(all_controls+group_offset);
476 group->cy = hold_for_group - group->y;
477 group->cx = group_max_cx;
479 group = (LPDLGITEMTEMPLATEW)(all_controls+control_len);
483 group_offset = control_len;
487 control_len += len + padding;
490 if ( group_offset && !split_tabs )
492 LPDLGITEMTEMPLATEW group =
493 (LPDLGITEMTEMPLATEW)(all_controls+group_offset);
494 group->cy = y - group->y;
495 group->cx = group_max_cx;
502 tpl = HeapAlloc(GetProcessHeap(),0,sizeof(DLGTEMPLATE) + 3*sizeof(WORD) +
505 tpl->style = WS_VISIBLE | WS_OVERLAPPEDWINDOW;
506 tpl->dwExtendedStyle = 0;
507 tpl->cdit = control_count;
510 tpl->cx = max_cx + 10;
512 ptr = (LPBYTE)tpl + sizeof(DLGTEMPLATE);
513 *(LPWORD)ptr = 0x0000;
515 *(LPWORD)ptr = 0x0000;
517 *(LPWORD)ptr = 0x0000;
519 memcpy(ptr,all_controls,control_len);
521 HeapFree(GetProcessHeap(),0,all_controls);
526 BOOL DoScannerUI(activeDS *pSource)
529 PROPSHEETPAGEW psp[10];
531 PROPSHEETHEADERW psh;
541 memset(&psp,0,sizeof(psp));
542 rc = sane_control_option(pSource->deviceHandle, 0, SANE_ACTION_GET_VALUE,
545 while (index < optcount)
547 const SANE_Option_Descriptor *opt;
548 psp[page_count].u.pResource = create_options_page(hdc, pSource, &index,
550 opt = sane_get_option_descriptor(pSource->deviceHandle, index);
552 if (opt->type == SANE_TYPE_GROUP)
557 len = MultiByteToWideChar(CP_ACP,0,opt->title,-1,NULL,0);
558 title = HeapAlloc(GetProcessHeap(),0,len * sizeof(WCHAR));
559 MultiByteToWideChar(CP_ACP,0,opt->title,-1,title,len);
561 psp[page_count].pszTitle = title;
564 if (psp[page_count].u.pResource)
566 psp[page_count].dwSize = sizeof(PROPSHEETPAGEW);
567 psp[page_count].dwFlags = PSP_DLGINDIRECT | PSP_USETITLE;
568 psp[page_count].hInstance = DSM_instance;
569 psp[page_count].pfnDlgProc = DialogProc;
570 psp[page_count].lParam = (LPARAM)pSource;
577 len = lstrlenA(device_list[pSource->deviceIndex]->vendor)
578 + lstrlenA(device_list[pSource->deviceIndex]->model) + 2;
580 szCaption = HeapAlloc(GetProcessHeap(),0,len *sizeof(WCHAR));
581 MultiByteToWideChar(CP_ACP,0,device_list[pSource->deviceIndex]->vendor,-1,
583 szCaption[lstrlenA(device_list[pSource->deviceIndex]->vendor)] = ' ';
584 MultiByteToWideChar(CP_ACP,0,device_list[pSource->deviceIndex]->model,-1,
585 &szCaption[lstrlenA(device_list[pSource->deviceIndex]->vendor)+1],len);
587 psh.dwSize = sizeof(PROPSHEETHEADERW);
588 psh.dwFlags = PSH_PROPSHEETPAGE|PSH_PROPTITLE|PSH_USECALLBACK;
589 psh.hwndParent = DSM_parentHWND;
590 psh.hInstance = DSM_instance;
592 psh.pszCaption = szCaption;
593 psh.nPages = page_count;
594 psh.u2.nStartPage = 0;
595 psh.u3.ppsp = (LPCPROPSHEETPAGEW) &psp;
596 psh.pfnCallback = PropSheetProc;
598 psrc = PropertySheetW(&psh);
600 for(index = 0; index < page_count; index ++)
602 HeapFree(GetProcessHeap(),0,(LPBYTE)psp[index].u.pResource);
603 HeapFree(GetProcessHeap(),0,(LPBYTE)psp[index].pszTitle);
612 static void UpdateRelevantEdit(HWND hwnd, const SANE_Option_Descriptor *opt,
613 int index, int position)
619 LoadStringA(DSM_instance, opt->unit, unit,20);
621 if (opt->type == SANE_TYPE_INT)
625 if (opt->constraint.range->quant)
626 si = position * opt->constraint.range->quant;
630 sprintf(buffer,"%i %s",si,unit);
633 else if (opt->type == SANE_TYPE_FIXED)
637 s_quant = SANE_UNFIX(opt->constraint.range->quant);
640 dd = position * s_quant;
642 dd = position * 0.01;
644 sprintf(buffer,"%f %s",dd,unit);
649 edit_w = GetDlgItem(hwnd,index+ID_BASE+ID_EDIT_BASE);
650 if (edit_w && buffer[0])
651 SetWindowTextA(edit_w,buffer);
655 static BOOL UpdateSaneScrollOption(activeDS *pSource,
656 const SANE_Option_Descriptor *opt, int index, DWORD position)
658 SANE_Status rc = SANE_STATUS_GOOD;
661 if (opt->type == SANE_TYPE_INT)
665 if (opt->constraint.range->quant)
666 si = position * opt->constraint.range->quant;
670 rc = sane_control_option (pSource->deviceHandle,index,
671 SANE_ACTION_SET_VALUE, &si, &result);
674 else if (opt->type == SANE_TYPE_FIXED)
679 s_quant = SANE_UNFIX(opt->constraint.range->quant);
682 dd = position * s_quant;
684 dd = position * 0.01;
686 sf = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));
690 rc = sane_control_option (pSource->deviceHandle,index,
691 SANE_ACTION_SET_VALUE, sf, &result);
693 HeapFree(GetProcessHeap(),0,sf);
696 if(rc == SANE_STATUS_GOOD)
698 if (result & SANE_INFO_RELOAD_OPTIONS ||
699 result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT)
705 static BOOL UpdateSaneBoolOption(activeDS *pSource, int index, BOOL position)
707 SANE_Status rc = SANE_STATUS_GOOD;
713 rc = sane_control_option (pSource->deviceHandle,index,
714 SANE_ACTION_SET_VALUE, &si, &result);
716 if(rc == SANE_STATUS_GOOD)
718 if (result & SANE_INFO_RELOAD_OPTIONS ||
719 result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT)
725 static BOOL UpdateSaneStringOption(activeDS *pSource, int index,
728 SANE_Status rc = SANE_STATUS_GOOD;
731 rc = sane_control_option (pSource->deviceHandle,index,
732 SANE_ACTION_SET_VALUE, value, &result);
734 if(rc == SANE_STATUS_GOOD)
736 if (result & SANE_INFO_RELOAD_OPTIONS ||
737 result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT)
743 static INT_PTR InitializeDialog(HWND hwnd, activeDS *pSource)
750 rc = sane_control_option(pSource->deviceHandle, 0, SANE_ACTION_GET_VALUE,
753 for ( i = 1; i < optcount; i++)
755 const SANE_Option_Descriptor *opt;
757 control = GetDlgItem(hwnd,i+ID_BASE);
762 opt = sane_get_option_descriptor(pSource->deviceHandle, i);
764 TRACE("%i %s %i %i\n",i,opt->title,opt->type,opt->constraint_type);
766 if (!SANE_OPTION_IS_ACTIVE(opt->cap))
767 EnableWindow(control,FALSE);
769 EnableWindow(control,TRUE);
771 SendMessageA(control,CB_RESETCONTENT,0,0);
772 /* initialize values */
773 if (opt->type == SANE_TYPE_STRING && opt->constraint_type !=
774 SANE_CONSTRAINT_NONE)
778 while (opt->constraint.string_list[j]!=NULL)
780 SendMessageA(control,CB_ADDSTRING,0,
781 (LPARAM)opt->constraint.string_list[j]);
784 sane_control_option(pSource->deviceHandle, i, SANE_ACTION_GET_VALUE, buffer,NULL);
785 SendMessageA(control,CB_SELECTSTRING,0,(LPARAM)buffer);
787 else if (opt->type == SANE_TYPE_BOOL)
790 sane_control_option(pSource->deviceHandle, i,
791 SANE_ACTION_GET_VALUE, &b, NULL);
793 SendMessageA(control,BM_SETCHECK,BST_CHECKED,0);
796 else if (opt->constraint_type == SANE_CONSTRAINT_RANGE)
798 if (opt->type == SANE_TYPE_INT)
803 min = (SANE_Int)opt->constraint.range->min /
804 (((SANE_Int)opt->constraint.range->quant)?
805 (SANE_Int)opt->constraint.range->quant:1);
807 max = (SANE_Int)opt->constraint.range->max /
808 (((SANE_Int)opt->constraint.range->quant)
809 ?(SANE_Int)opt->constraint.range->quant:1);
811 SendMessageA(control,SBM_SETRANGE,min,max);
813 sane_control_option(pSource->deviceHandle, i,
814 SANE_ACTION_GET_VALUE, &si,NULL);
815 if (opt->constraint.range->quant)
816 si = si / opt->constraint.range->quant;
818 SendMessageW(control,SBM_SETPOS, si, TRUE);
819 UpdateRelevantEdit(hwnd, opt, i, si);
821 else if (opt->type == SANE_TYPE_FIXED)
826 double s_min,s_max,s_quant;
830 s_min = SANE_UNFIX(opt->constraint.range->min);
831 s_max = SANE_UNFIX(opt->constraint.range->max);
832 s_quant = SANE_UNFIX(opt->constraint.range->quant);
836 min = (s_min / s_quant);
837 max = (s_max / s_quant);
845 SendMessageA(control,SBM_SETRANGE,min,max);
848 sf = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));
849 sane_control_option(pSource->deviceHandle, i,
850 SANE_ACTION_GET_VALUE, sf,NULL);
852 dd = SANE_UNFIX(*sf);
853 HeapFree(GetProcessHeap(),0,sf);
856 pos = (dd / s_quant);
860 SendMessageW(control, SBM_SETPOS, pos, TRUE);
862 UpdateRelevantEdit(hwnd, opt, i, pos);
870 static INT_PTR ProcessScroll(HWND hwnd, activeDS *pSource, WPARAM wParam,
874 const SANE_Option_Descriptor *opt;
878 index = GetDlgCtrlID((HWND)lParam)- ID_BASE;
882 opt = sane_get_option_descriptor(pSource->deviceHandle, index);
887 scroll = LOWORD(wParam);
892 case SB_THUMBPOSITION:
895 si.cbSize = sizeof(SCROLLINFO);
896 si.fMask = SIF_TRACKPOS;
897 GetScrollInfo((HWND)lParam,SB_CTL, &si);
898 position = si.nTrackPos;
904 position = SendMessageW((HWND)lParam,SBM_GETPOS,0,0);
910 position = SendMessageW((HWND)lParam,SBM_GETPOS,0,0);
914 position = SendMessageW((HWND)lParam,SBM_GETPOS,0,0);
917 SendMessageW((HWND)lParam,SBM_SETPOS, position, TRUE);
918 position = SendMessageW((HWND)lParam,SBM_GETPOS,0,0);
920 UpdateRelevantEdit(hwnd, opt, index, position);
921 if (UpdateSaneScrollOption(pSource, opt, index, position))
922 InitializeDialog(hwnd,pSource);
928 static void ButtonClicked(HWND hwnd, activeDS* pSource,INT id, HWND control)
931 const SANE_Option_Descriptor *opt;
933 index = id - ID_BASE;
937 opt = sane_get_option_descriptor(pSource->deviceHandle, index);
942 if (opt->type == SANE_TYPE_BOOL)
944 BOOL r = SendMessageW(control,BM_GETCHECK,0,0)==BST_CHECKED;
945 if (UpdateSaneBoolOption(pSource, index, r))
946 InitializeDialog(hwnd,pSource);
950 static void ComboChanged(HWND hwnd, activeDS* pSource,INT id, HWND control)
955 const SANE_Option_Descriptor *opt;
958 index = id - ID_BASE;
962 opt = sane_get_option_descriptor(pSource->deviceHandle, index);
967 selection = SendMessageW(control,CB_GETCURSEL,0,0);
968 len = SendMessageW(control,CB_GETLBTEXTLEN,selection,0);
971 value = HeapAlloc(GetProcessHeap(),0,len);
972 SendMessageA(control,CB_GETLBTEXT,selection,(LPARAM)value);
974 if (opt->type == SANE_TYPE_STRING)
976 if (UpdateSaneStringOption(pSource, index, value))
977 InitializeDialog(hwnd,pSource);
982 static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
984 static activeDS *pSource = NULL;
989 pSource = (activeDS*)((LPPROPSHEETPAGEW)lParam)->lParam;
990 return InitializeDialog(hwndDlg, pSource);
992 return ProcessScroll(hwndDlg, pSource, wParam, lParam);
996 LPPSHNOTIFY psn = (LPPSHNOTIFY)lParam;
997 switch (((NMHDR*)lParam)->code)
1000 if (psn->lParam == TRUE)
1002 pSource->currentState = 6;
1003 pSource->pendingEvent.TWMessage = MSG_XFERREADY;
1006 case PSN_QUERYCANCEL:
1007 pSource->pendingEvent.TWMessage = MSG_CLOSEDSREQ;
1010 InitializeDialog(hwndDlg, pSource);
1016 switch (HIWORD(wParam))
1019 ButtonClicked(hwndDlg, pSource,LOWORD(wParam),
1023 ComboChanged(hwndDlg, pSource,LOWORD(wParam),
1032 static int CALLBACK PropSheetProc(HWND hwnd, UINT msg, LPARAM lParam)
1034 if (msg == PSCB_INITIALIZED)
1036 /* rename OK button to Scan */
1037 HWND scan = GetDlgItem(hwnd,IDOK);
1038 SetWindowTextA(scan,"Scan");
1044 static INT_PTR CALLBACK ScanningProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
1049 HWND ScanningDialogBox(HWND dialog, DWORD progress)
1052 dialog = CreateDialogW(DSM_instance,
1053 (LPWSTR)MAKEINTRESOURCE(IDD_DIALOG1), NULL, ScanningProc);
1057 EndDialog(dialog,0);
1061 RedrawWindow(dialog,NULL,NULL,
1062 RDW_INTERNALPAINT|RDW_UPDATENOW|RDW_ALLCHILDREN);
1067 #else /* HAVE_SANE */
1069 BOOL DoScannerUI(activeDS *pSource)
1074 #endif /* HAVE_SANE */