Укажите отработанное время

Отработанное время:
Продуктивное время:
Bug 2796 - Инфо Бухгалтер (сетевая): неправильно отображается дерево папок при выборе базы   Make a simular bug
Summary: Инфо Бухгалтер (сетевая): неправильно отображается дерево папок при выборе базы
Status: CLOSED FIXED
Alias: None
Product: WINE@Etersoft
Classification: Продукты (Products)
Component: Окна / фокус / перерисовка (show other bugs)
Version: 1.0.9
Hardware: PC All
: P3 minor
Target Milestone: ---
Assignee: Денис Баранов
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 2792
Blocks: 2814 2710
  Show dependency treegraph
 
In work:
Reported: 2008-11-01 20:51 MSK by Денис Баранов
Modified: 2009-04-25 14:54 MSD (History)
3 users (show)

See Also:
Заявки RT:
Связано с:
Дата напоминания:


Attachments
В вайне (6.93 KB, image/png)
2010-11-18 03:58 MSK, Денис Баранов
Details
В винде (85.30 KB, image/png)
2010-11-18 03:58 MSK, Денис Баранов
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Денис Баранов 2008-11-01 20:51:55 MSK
Created attachment 856 [details]
В вайне

Соответственно при нажатии на кнопку «ОК» происходит переход на уровень выше, т.к. папка с базой не выбрана (нужен стандартный OpenFileDialog без OFN_EXPLORER).
См.скрины.
При установке программы выбрать «Сетевая с локальным ключом».
Comment 1 Денис Баранов 2008-11-01 20:52:34 MSK
Created attachment 857 [details]
В винде
Comment 2 Виталий Перов 2008-11-10 19:57:20 MSK
Ошибка воспроизвелась.
Используется функция GetOpenFileNameA которая вызывает
GetFileName31A
Comment 3 Виталий Перов 2008-11-10 21:20:44 MSK
шаблон диалога загружается с помощью:
hResInfo = FindResourceA(priv->ofnA->hInstance,
				 priv->ofnA->lpTemplateName,
                                 (LPSTR)RT_DIALOG);

структура priv->ofnA заполняется при инициализации FD32_Init и берётся она из 
priv->ofnA = (LPOPENFILENAMEA) lParam;
инициализация вызывается из функции FD31_AllocPrivate, а в качестве lParam туда передаётся lpofn. 
Таким образом шаблон должен браться изlpofn->lpTemlateName,

Проверил, при вызове диалога этот параметр не NULL

Если я правильно понял, то этот диалог берётся из ресурсов самой программы
Comment 4 Виталий Перов 2008-11-10 21:50:56 MSK
сообщения диалога обрабатываются в функции FD31_WMCommand

При нажатии ОК вызывается
FD31_Validate, которая проверяет выбрано ли правильное имя файла. Если да, то закрывает диалог.

В данном случае при нажатии ОК диалог никогда не закроется т.к файл не выбран.
Comment 5 Виталий Перов 2008-11-10 22:02:20 MSK
Если FD31_Validate не вызывать, то диалог закрывается, но вместе с ним закрывается и сама программа. Возможно, что возвращается ошибка или пустой путь.
Надо писать тест.
Comment 6 Виталий Перов 2008-11-11 17:14:01 MSK
Имя файла заносится в соответствующую структуру только при выборе файла.

Для контрола directoryList обрабатывается событие LBN_DBLCLK, но при этом также результат не отражается на выходной структуре.

Дописал в обработку события LBN_DBLCLK добавление выбранного пути.
Теперь lfs->ofnW->lpstrFile добавляется полный путь.
Проверил, при нажатии на ОК, перед закрытием диалога путь сохраняется, но программа по-прежнему закрывается при нажатии на ОК.

Без теста тут не обойтись.
Comment 7 Виталий Перов 2008-11-11 17:51:57 MSK
Можно использовать стандартный тест, лежащий в programs/cmdlgtst
для отображения диалога в стиле win31 надо чтобы 1 из флагов (OFN_ALLOWMULTISELECT|OFN_ENABLEHOOK|OFN_ENABLETEMPLATE) был выставлен.
Comment 8 Виталий Перов 2008-11-11 19:58:30 MSK
Тест показал, что после закрытия поле, где должно содержаться имя файла - пустое, хотя перед закрытием диалога там содержится (проверял!) имя выбранной директории.

Если при нажатии на ОК всё-таки вызывать FD31_Validate, то результат нормально возвращается, но диалог завершается только при выборе директории.

Проблема в проверке полученного файла функцией FD31_TestPath():
При выборе директории она возвращает false, затем FD31_Validate возвращает false, и диалог не завершается.

В тесте в эту функцию передаётся filename = '*.*';
Можно не возвращать в FD31_Validate false при неправильном завершении FD31_TestPath(), если filename = '*.*'
После данного исправления, тест начинает нормально работать:
При нажатии на ОК возвращается выбранная директория.

Но сама программа не работает. В этом месте filename = '';
Воспроизвести такую ситуацию на тесте при выставлении различных флагов не удаётся
Comment 9 Виталий Перов 2008-11-13 16:35:37 MSK
Необходимо проверить как ведёт себя данный диалог в Windows.

Для этого необходимо дописать тестовую программу, и скомпиллировать её для запуска под Windows.
Comment 10 Виталий Перов 2008-11-13 17:27:08 MSK
Взял тест из programs/cmdlgtst, урезал его так, чтобы остался только тест на диалог открытия файла.
Дописал вывод дополнительных параметров.

Проверил на win2k3.
Выбрать папку не получается! пробовал ставить различные флаги - папка всё-равно не выбирается, только файлы.

Необходимо посмотреть с какими флагами вызывает этот диалог Инфо бухгалтер
Comment 11 Виталий Перов 2008-11-13 17:44:18 MSK
флаги = 6240 или 0x1860 , что соответствует OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK 
Comment 12 Виталий Перов 2008-11-13 21:21:42 MSK
Пропробовал выставить такие же флаги (кроме OFN_ENABLETEMPLATE) - ничего не изменилось.

Реализовал функцию нотификации в тесте. Теперь туда отправляются все сообщения из диалога открытия.
Можно попробовать отлавливать только нужные, например выбор файлов, выбор папок, и нажатие на ОК, а остальные просто игнорировать.
Можно также расшифровывать параметры данных сообщений, чтобы получить строки, содержащие название выбранного элемента
А затем сравнить данные в wine и в Windows, но думаю это ни к чему не приведёт.

При закрытии диалога программа как-то проверяет полученные данные, и найдя ошибку закрывается. Но что конкретно её не нравится определить не получается.

Отправил разработчикам просьбу предоставить исходники. 
Comment 13 Виталий Перов 2008-11-15 15:26:24 MSK
На запрос исходников был получен ответ:
>Как я уже описывал в сообшении о найденых ошибках (на всякий случай 
>посылаю его еще раз), в данном случае используется стандартный 
>OpenFileDialog без OFN_EXPLORER, если 2 раза щелкнуть на поле, где 
>должно отображаться дерево папок, выдается сообщение об ошибке 4104 в 
>функции GetOpenFileName, но база открывается и работать можно (если базы 
>в папке нет, она создается).

Проверил на wine: действительно, по двойному щелчку на пустом месте в дереве папок выбирается именно нужная директория.

Проверил на винде: ситуация противоположная: работает выбора бызы по OK и по двойному щелчку по названию папки, но не работает по двойному щелчку по пустому месту.

Заметил ещё одну особенность между запуском диалога из инфобухгалтера и запуском в тесте под win2k3:
Слева расположен список с файлами в текущей директории, а над списком редактируемое поле, содержащие имя файла. Такое поле есть при тестировании по win2k3, но его нет при вызове диалога из инфо-бухгалтер. (возможно причина в том, что инфобухгалтер использует свой шаблон диалога)

Comment 14 Виталий Перов 2008-11-15 17:50:36 MSK
Ещё раз проверил поведение теста с диалогом в windows. Изменением параметров никак не удалось добиться того, чтобы диалог принимал директорию в качестве выбора пользователся.
Отсюда вывод: стандартными средствами сделать это нельзя.
Единственный способ (как мне кажется) это сделать - это ловить сообщения с помощью функции нотификации.

При трейсе по каналу relay, получил довольно интересную активность функции нотификации (которая реализована в инфо-бухгалтере):
fixme:commdlg:FD32_CallWindowProc Call hookA 0x3e1a0c (0x40060, 0400, 0000038d, 00000000----------------------)
0032:Call KERNEL32.GetCurrentDirectoryA(00000103,003ed158) ret=003e1a58
0032:Ret  KERNEL32.GetCurrentDirectoryA() retval=00000018 ret=003e1a58
0032:Call KERNEL32.FindClose(ffffffff) ret=003e5bac
0032:Ret  KERNEL32.FindClose() retval=00000000 ret=003e5bac
0032:Call KERNEL32.FindFirstFileA(0032e068 "C:\\IB\\ORN\\Ibw8NetL\\ARHIV\\ibw.dcf",0032dde0) ret=003e5d4e
0032:Ret  KERNEL32.FindFirstFileA() retval=ffffffff ret=003e5d4e
0032:Call KERNEL32.GetLastError() ret=003e721a
0032:Ret  KERNEL32.GetLastError() retval=00000002 ret=003e721a
0032:Call KERNEL32.FindResourceExA(003e0000,00000006,00000001,00000400) ret=003e2705
0032:Ret  KERNEL32.FindResourceExA() retval=003f4130 ret=003e2705
0032:Call KERNEL32.LoadResource(003e0000,003f4130) ret=003e2715
0032:Ret  KERNEL32.LoadResource() retval=003f4670 ret=003e2715
0032:Call KERNEL32.LockResource(003f4670) ret=003e2726
0032:Ret  KERNEL32.LockResource() retval=003f4670 ret=003e2726
0032:Call KERNEL32.WideCharToMultiByte(000004e3,00000000,003f4674 L"База данных неопределенаНазвание базы: ",00000018,0032df68,000001ff,00000000,00000000) ret=003e275f
0032:Ret  KERNEL32.WideCharToMultiByte() retval=00000018 ret=003e275f
0032:Call KERNEL32.FreeResource(003f4670) ret=003e2787
0032:Ret  KERNEL32.FreeResource() retval=00000000 ret=003e2787
0032:Call KERNEL32.FindResourceExA(003e0000,00000006,00000001,00000400) ret=003e2705
0032:Ret  KERNEL32.FindResourceExA() retval=003f4130 ret=003e2705
0032:Call KERNEL32.LoadResource(003e0000,003f4130) ret=003e2715
0032:Ret  KERNEL32.LoadResource() retval=003f4670 ret=003e2715
0032:Call KERNEL32.LockResource(003f4670) ret=003e2726
0032:Ret  KERNEL32.LockResource() retval=003f4670 ret=003e2726
0032:Call KERNEL32.WideCharToMultiByte(000004e3,00000000,003f46a6 L"Название базы: ",0000000f,0032df68,000001ff,00000000,00000000) ret=003e275f
0032:Ret  KERNEL32.WideCharToMultiByte() retval=0000000f ret=003e275f
0032:Call KERNEL32.FreeResource(003f4670) ret=003e2787
0032:Ret  KERNEL32.FreeResource() retval=00000000 ret=003e2787
0032:Call user32.SetDlgItemTextA(00040060,000007d1,003efd78 "\xcd\xe0\xe7\xe2\xe0\xed\xe8\xe5 \xe1\xe0\xe7\xfb: \xc1\xe0\xe7\xe0 \xe4\xe0\xed\xed\xfb\xf5 \xed\xe5\xee\xef\xf0\xe5\xe4\xe5\xeb\xe5\xed\xe0") ret=003e1afe
0032:Call window proc 0x7ee92190 (hwnd=0x40046,msg=WM_SETTEXT,wp=00000000,lp=003efd78)
0032:Call window proc 0x7ee46ee0 (hwnd=0x40060,msg=WM_CTLCOLORSTATIC,wp=0000030c,lp=00040046)
0032:Call dialog proc 0x7e96125d (hwnd=0x40060,msg=WM_CTLCOLORSTATIC,wp=0000030c,lp=00040046)
0032:Call user32.GetPropA(00040060,7e97a734 "FILEDLG_OFN") ret=7e961289
0032:Ret  user32.GetPropA() retval=001916d8 ret=7e961289
fixme:commdlg:FD32_CallWindowProc Call hookA 0x3e1a0c (0x40060, 0138, 0000030c, 00040046----------------------)
fixme:commdlg:FD32_CallWindowProc ret hookA 0x3e1a0c (0x40060, 0138, 0000030c, 00040046-----------------------)
0032:Ret  dialog proc 0x7e96125d (hwnd=0x40060,msg=WM_CTLCOLORSTATIC,wp=0000030c,lp=00040046) retval=00000000 result=00000000
0032:Ret  window proc 0x7ee46ee0 (hwnd=0x40060,msg=WM_CTLCOLORSTATIC,wp=0000030c,lp=00040046) retval=0000010c
0032:Ret  window proc 0x7ee92190 (hwnd=0x40046,msg=WM_SETTEXT,wp=00000000,lp=003efd78) retval=00000001
0032:Ret  user32.SetDlgItemTextA() retval=00000001 ret=003e1afe
fixme:commdlg:FD32_CallWindowProc ret hookA 0x3e1a0c (0x40060, 0400, 0000038d, 00000000-----------------------)
Comment 15 Виталий Перов 2008-11-15 20:24:39 MSK
Разобрался, чтобы начала работать клавиша ОК, необходимо при её нажатии посылать дополнительное сообщение в функцию нотификации.
При добавлении:
        
if (lfs->hook)
        {
            if (FD31_CallWindowProc(lfs, lfs->lbselchstring, lst2,
                    MAKELONG(0,CD_LBSELCHANGE)))
                return TRUE;
        }
инфо-бухгалтер начинает адекватно реагировать на нажатие ОК.
Comment 16 Виталий Перов 2008-11-15 20:58:55 MSK
Патч отослал.
Должен появиться в следующей сборке (сейчас сборка 34.1)
Прошу протестировать
Comment 17 Денис Баранов 2008-11-16 19:14:54 MSK
Протестировано. Патч исправляет проблему.
Ждем новую сборку.