Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB6 > переносимость. commondialog


Автор: suvorr 14.10.2006, 10:28
 Уже писал про это (и не только я) но никак не могу получить окончательного удовлетворения!
Для открытия файлов использую CommonDialog (а как еще?)
CommonDialog сидит в cmdlg32.dll которого на многих машинах нет (кстати кто его ставит -Windows или VB?). В результате чего юзеры теряются!
Уже давно смирился. Но тут попал на машину где cmdlg  нет и вдруг IE на команду "открыть файл" выдает то самое окошко!
Вопрос -КАААК?  Спасибо

Автор: Тутанхамец 14.10.2006, 14:59
cmdlg.ocx - это просто объектная оболочка для APIшных функций GetOpenFileName, GetSaveFileName и пр.

Автор: JusTalionis 16.10.2006, 14:33
Вместо Common Dialog пользуйся для этого API.
Как воспользоваться, я подробно объяснял в своем ответе вот на этот топик: http://www.forum.vingrad.ru/index.php?showtopic=104868
В этом методе будет использован файл comdlg32.dll, входящий в состав Виндов, им и пользуются остальные проги.

Автор: suvorr 17.10.2006, 08:53
Hi, JusTalionis! Весьма спасибо! Твой код работает. Но возник странный такой трабл - если перед вызовом GetOpenFileName загнать в FileBox.lpstrfile  некоторый файл предлагаемый юзеру "по умолчанию", а он его не захочет и выберет более длинный, то она, собака, режет его до длины предложенного! Несмотря на filebox.nmaxfile=255! Не наступал ли ты на это ?

Автор: JusTalionis 17.10.2006, 12:38
FileBox.lpstrfile  - это и есть буфер для ввода имени файла: оно вводится конкретно в тело заданной строки. Если данные длиннее ее, конечно усекутся. У меня написано: space(255) - это строка из 255 пробелов. А ты ее заменил просто своим именем? надо было дополнить пробелами в конце до 255 знаков.

Автор: suvorr 1.11.2006, 11:40
ХА-ХА! Вы конечно будете смеяться, но под Windows XP код не работает !!!! Пишет RunTime Error 5 -неправильный вызов функции !!!  За что боролись ??? А под 98 работает!  Короче поставил я простой InputBox и прошу юзера набирать ручками !!!  Хотя фонарею при этом - такая элементарная вещь -выбор файла - и никак не сделать что бы везде работало !!

Автор: mihanik 1.11.2006, 11:45
Ты здесь читал - http://forum.vingrad.ru/s/f21d0a7d04b29129ab4c57f0c3f42314/topic-118488.html ?

Код

Option Explicit

''''''''''''''''''''
' Модуль для выбора ПОЛНОГО ИМЕНИ ФАЙЛА
'
' Используемые аргументы
'   strIniFolder - начальная папка
'
' Используемые API-функции
'   GetOpenFileName
'
''''''''''''''''''''

' Определяем структуру/тип для вызова API-функции
Type OPENFILENAME
    lStructSize         As Long
    hwndOwner           As Long
    hInstance           As Long
    lpstrFilter         As String
    lpstrCustomFilter   As String
    nMaxCustFilter      As Long
    nFilterIndex        As Long
    lpstrFile           As String
    nMaxFile            As Long
    lpstrFileTitle      As String
    nMaxFileTitle       As Long
    lpstrInitialDir     As String
    lpstrTitle          As String
    flags               As Long
    nFileOffset         As Integer
    nFileExtension      As Integer
    lpstrDefExt         As String
    lCustData           As Long
    lpfnHook            As Long
    lpTemplateName      As String
End Type

' определяем API-функцию
Declare Function GetOpenFileName Lib "comdlg32.dll" _
                 Alias "GetOpenFileNameA" (pOPENFILENAME As OPENFILENAME) As Long

' Описываем непосредственно саму функцию получения имени файла
Function strFileName(ByVal strIniFolder As String) As String

    ' Определяем переменные
    Dim OpenFile As OPENFILENAME
    Dim sFilter As String

    ' Заполним структуру для вызова функции GetOpenFileName
    OpenFile.lStructSize = Len(OpenFile)
    OpenFile.hwndOwner = 0
    OpenFile.hInstance = 0
    
    ' Определяем маску для отображаемых файлов
    sFilter = "Text Files " & Chr$(0) & "*.txt" & Chr$(0) & _
              "MS Word Files " & Chr$(0) & "*.doc" & Chr$(0) & _
              "All files " & Chr$(0) & "*.*" & Chr$(0)
              
    ' Продолжаем заполнение структуры
    OpenFile.lpstrFilter = sFilter
    OpenFile.nFilterIndex = 1
    OpenFile.lpstrFile = String$(255, 0)
    OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1
    OpenFile.lpstrFileTitle = OpenFile.lpstrFile
    OpenFile.nMaxFileTitle = OpenFile.nMaxFile
    OpenFile.lpstrInitialDir = "strIniFolder"
    OpenFile.lpstrTitle = "Open..."
    OpenFile.flags = 0
    
    ' Вызываем API-функцию
    GetOpenFileName OpenFile

    ' Получаем полное имя afqkf
    strFileName = OpenFile.lpstrFile
    
End Function


Автор: JusTalionis 1.11.2006, 16:00
Цитата(suvorr @  1.11.2006,  11:40 Найти цитируемый пост)
фонарею при этом - такая элементарная вещь -выбор файла - и никак не сделать что бы везде работало !! 

По сему лично я сижу пока на 98, и по ХП проверить, к сожалению, не могу.
Благодарности - Биллу Г. !



Автор: suvorr 1.11.2006, 22:28
Mihanik-y. Что ты имеешь в виду ? По моему твой код аналогичен  коду JusTalionis-a  Я на основе него сделал ппростенький код

Код

Public Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" _
(pOpenfilename As OPENFILENAME) As Long
Public Type OPENFILENAME
        lStructSize As Long
        hwndOwner As Long
        hInstance As Long
        lpstrFilter As String
        lpstrCustomFilter As String
        nMaxCustFilter As Long
        nFilterIndex As Long
        lpstrFile As String
        nMaxFile As Long
        lpstrFileTitle As String
        nMaxFileTitle As Long
        lpstrInitialDir As String
        lpstrTitle As String
        flags As Long
        nFileOffset As Integer
        nFileExtension As Integer
        lpstrDefExt As String
        lCustData As Long
        lpfnHook As Long
        lpTemplateName As String
End Type
Public Function GetFile(titl As String, defl As String) As String
Dim ff As OPENFILENAME, aa As Long
ff.lStructSize = Len(ff)  ' размер структуры
ff.lpstrTitle = titl  ' текст для заголовка диалогового окна
ff.lpstrFile = defl + Space(200) ' создаем буфер для приема пути и имени файла
ff.nMaxFile = 200  ' длина буфера
aa = GetOpenFileName(ff)
G = Trim(ff.lpstrFile):  GetFile = Left(G, Len(G) - 1)
End Function


он нормально пашет на 98 а на XP Run Time Error !!! Invalid function call !!!   Я думаю в 98 и в ХП эта GetOPenFileName разная !
Или я чего не понял в твоем коде ?

Автор: mihanik 2.11.2006, 08:13
Странно...

У меня и на XP, и на  XP SP1, и на XP SP2 этот код пашет нормально...

Даже на 2000 SP4 пашет...
 smile 

Автор: Тутанхамец 2.11.2006, 10:54
Нечего хаять Билла. 
Имхо, в этом коде ты не правильно  (не полностью) заполняешь структуру. Поэтому у тебя не срабатывает GetOpenFileName и возвращает FALSE. И не отображает диалоговое окно. А ран-тайм еррор 5 возникает, когда ты пытаешь отрезать Left'ом часть строки, в которой нет ни одного символа. Откуда там сивмолы, если GetOpenFileName запоролась? Ты бы поставил брекпойнт на процедуру и посмотрел, где возникает ошибка. 

Автор: mihanik 2.11.2006, 11:23
Заметил маленькую ошибку в своём коде...

Вместо

Код

OpenFile.lpstrInitialDir = "strIniFolder"

надо писать

Код

OpenFile.lpstrInitialDir = strIniFolder

Автор: suvorr 2.11.2006, 22:18
Тутанхамцу 
- Спасибо, понял, исправлюсь !
- Ну посмотреть то я не мог поскольку у меня ХП нет, мне просто юзер с ХП сообщил что там происходит. 
- А всеж таки выходит что ХП тупее 98 !

Автор: suvorr 4.11.2006, 13:59
Тутанхамцу:    Так вот же нет !!!
Взял я полный код Механика с учетом его поправки, но за минусом маски
Код

Public Declare Function GetOpenFileName Lib "comdlg32.dll" Alias "GetOpenFileNameA" _
(pOpenfilename As OPENFILENAME) As Long
Public Type OPENFILENAME
        lStructSize As Long
        hwndOwner As Long
        hInstance As Long
        lpstrFilter As String
        lpstrCustomFilter As String
        nMaxCustFilter As Long
        nFilterIndex As Long
        lpstrFile As String
        nMaxFile As Long
        lpstrFileTitle As String
        nMaxFileTitle As Long
        lpstrInitialDir As String
        lpstrTitle As String
        flags As Long
        nFileOffset As Integer
        nFileExtension As Integer
        lpstrDefExt As String
        lCustData As Long
        lpfnHook As Long
        lpTemplateName As String
End Type
Public Function GetFile(titl As String, defl As String) As String
Dim OpenFile As OPENFILENAME
    OpenFile.lStructSize = Len(OpenFile)
    OpenFile.hwndOwner = 0
    OpenFile.hInstance = 0
    sFilter = "*.*"
    OpenFile.lpstrFilter = sFilter
    OpenFile.nFilterIndex = 1
    OpenFile.lpstrFile = String$(255, 0)
    OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1
    OpenFile.lpstrFileTitle = OpenFile.lpstrFile
    OpenFile.nMaxFileTitle = OpenFile.nMaxFile
    OpenFile.lpstrInitialDir = strIniFolder
    OpenFile.lpstrTitle = titl
    OpenFile.flags = 0
GetOpenFileName OpenFile
GetFile = Trim(OpenFile.lpstrFile):
MsgBox GetFile + "L":
End Function


И он вроде как работает (под 98) но приплюснутое "L" не печатает !!!
То есть в GetFile  меня не строка а черт те что!
Что потом индуцирует ошибки
А что уж там в ХП получится ....

Модератору (если увидит) -какого... мне стали каждый раз писать что я не имею права добавлять реплики в мой собственный топик и прогонять через вход? Раньше вроде как автоматом входил ?

Автор: Тутанхамец 4.11.2006, 14:15
Со входом на форум - у тебя на компе небось кукисы не срабатывают. 

А что касается диалога, то смотри:
Код

...
GetOpenFileName OpenFile
GetFile = Trim(OpenFile.lpstrFile)
If Right$(GetFile, 1) = Chr(0) Then MsgBox "на конце ноль"
MsgBox GetFile + "L"
End Function


GetOpenFileName возвращает в выделенный буфер строку, оканчивающуюся нулем, то есть chr(0). Этот ноль воспринимается как конец строки. Можно прибавить после него хоть "L", хоть что и сколько угодно, но строка всё равно будет оканчиваться там, где ноль. 

Если хочешь что-то прибавить к строке, то сначала отрежь ноль. smile

Добавлено @ 14:20 
А в остальном твоя функция нормально работает под ХР.

Автор: suvorr 4.11.2006, 21:38
Да, точняк, у JusTalionisa это предусмотрено!

Автор: Тутанхамец 5.11.2006, 08:38
Не забудь предусмотреть ситуацию, когда юзер не выберет файл. Нажмет "Отмена" или крестик. Тогда у тебя опять же не будет строки, с которой ты оперируешь.

Автор: suvorr 5.11.2006, 09:28
Спасибо! 
Но возник еще вопрос - эта фигня насчет необходимости заполнения всех параметров и вообще насчет разницы претензий со стороны 98 и ХП -она для всех апишек актуальна или это только GetOpenFile так развлекается ?
 В частности чисто конкретно меня интересует семейство waveIn...  Правда пока на них никто не жаловался, но с другой стороны они у меня в таком закоулочке, что наверно немногие и добираются.

Автор: Тутанхамец 5.11.2006, 11:35
Цитата

она для всех апишек актуальна или

Боюсь, что это тебе придется устанавливать исключительно чувственным опытом smile
Имхо лучше строго следовать документации. Даже если что-то непредусмотренное документацией работает под 98 и ХР, нет гарантии, что будет работать под висту. Чел по имени Стефан Цвейг сказал, что "формальность - это гарантия". smile Хотя был бы он программистом, добавил бы: "чаще всего" или "обычно". smile

Автор: JusTalionis 3.10.2007, 11:15
Поскольку переносимость - моя больная мозоль, вот раскопал какую инфу:
Цитата
Компания LANDesk Software по договору с фирмой Thinstall будет предлагать под маркой LANDesk Application Virtualization разработанную той технологию виртуализации приложений, позволяющую "упаковать" любую программу в единственный .exe-файл, который может работать на ПК с привилегиями пользовательского уровня даже если программе требуется доступ к реестру и системным файлам. При этом не нужно устанавливать никаких дополнительных серверных либо клиентских приложений: "упакованная" программа доставляется по сети на пользовательский ПК (или переносится на USB-накопителе) и запускается в изолированной от основной системы среде, формирование которой обеспечивается 400-килобайтным кодом, добавляемым к .exe-файлу. Процесс упаковки каждого приложения занимает относительно немного времени и предусматривает его инсталляцию и дополнение "виртуальным реестром", который будет замещать системный в процессе исполнения. Программный продукт позволяет, например, запускать под управлением Windows Vista старые, не совместимые с новой ОС приложения, или пользоваться Internet Explorer 7 на одной машине с Internet Explorer 6. 
 ( http://www.osp.ru/news/2007/0523/4196869/ )

Вот был бы блеск - упаковывать сделанные Бейсиком проги со всеми прилагающимися .ocx-ами и .dll-ами smile 
Кто-нибудь слыхал - появилось это чудо в реале-то? Или так и затухло?


Автор: Тутанхамец 3.10.2007, 11:18
Еще под VB4 были такие упаковщики. 

ЗЫ В смысле, которые упаковывают все dll и ocx в один exe.

Автор: JusTalionis 3.10.2007, 11:25
Да нет, ты понял в чем дело? Прога не только упаковывает, а устраняет необходимость инсталляции. Просто запускаешь экзешник, возможно прямо на флешке.
А после тех упаковщиков надо же было инсталлировать, в процессе чего всё это снова распаковывалось.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)