:: Visual Foxpro, Foxpro for DOS
GetFile средствами API
Vladimir_Knyr

Сообщений: 1711
Откуда: г. Енисейск
Дата регистрации: 15.12.2003
вобщем возвращаясь к теме по заданию вида отображения файлов при открытии

навыискивал и вот что получилось:
WM_COMMAND = 273
oIE = createobject("InternetExplorer.Application.1")
oIE.Navigate("c:\")
lWnd = FindWindowEx(oIE.hwnd, 0, "SHELLDLL_DefView", 0)
*!* 28713 - Large icons
*!* 28714 - Small icons
*!* 28715 - List
*!* 28716 - Details
*!* 28717 - Thumbnails
*!* 28718 - Tiles
SendMessage(lWnd, WM_COMMAND, 28717, 0)
oIE.visible = .t.
*********************************************************
это только цветочки
чаще или почти всегда используем GetFile(), но он модальный

попробовал после открытия GetFile() подсунуть ему
SendMessage(lWnd, WM_COMMAND, 28717, 0) из другого процесса, прокатило,

но как то думаю корявенько это и малость громоздко

идея пришла попробовать так
hmwCreateWindowEx(...,"#32770",...)
SendMessage(...)
showwindow(...)
окно открылось голое

вот собственно и как это можно ли сделать из этого свой GetFile()
(с еще одним параметром - ViewMode - например)


------------------
хороший код работать будет и обязан, а плохой не жалко.
Ratings: 0 negative/0 positive
Re: GetFile средствами API
MichaelD

Сообщений: 7578
Дата регистрации: 14.05.2005
Возможно я чего-то не понял....
Но вот т.с. "более прямой код" с использованием GetOpenFileName из comdlg32.dll:

*////////////////////
#define OFN_PATHMUSTEXIST 0x00000800
#define OFN_FILEMUSTEXIST 0x00001000
#define OFN_EXPLORER 0x00080000
#define OFN_EX_NOPLACESBAR 0x00000001
#define N_SIZE_OPENFILENAME 88
*!* typedef struct tagOFN {
*!* DWORD lStructSize;
*!* HWND hwndOwner;
*!* HINSTANCE hInstance;
*!* LPCTSTR lpstrFilter;
*!* LPTSTR lpstrCustomFilter;
*!* DWORD nMaxCustFilter;
*!* DWORD nFilterIndex;
*!* LPTSTR lpstrFile;
*!* DWORD nMaxFile;
*!* LPTSTR lpstrFileTitle;
*!* DWORD nMaxFileTitle;
*!* LPCTSTR lpstrInitialDir;
*!* LPCTSTR lpstrTitle;
*!* DWORD Flags;
*!* WORD nFileOffset;
*!* WORD nFileExtension;
*!* LPCTSTR lpstrDefExt;
*!* LPARAM lCustData;
*!* LPOFNHOOKPROC lpfnHook;
*!* LPCTSTR lpTemplateName;
*!* #if (_WIN32_WINNT >= 0x0500)
*!* void * pvReserved;
*!* DWORD dwReserved;
*!* DWORD FlagsEx;
*!* #endif // (_WIN32_WINNT >= 0x0500)
*!* } OPENFILENAME, *LPOPENFILENAME;
*
*-- Test VFP version
ACTIVATE SCREEN
CLEAR
IF VERSION(5) < 900
? "Sorry, for VFP 9.0 (or later) :-("
RETURN .F.
ENDIF
*
*-- Declare Win32Api-functions
DECLARE INTEGER GetProcessHeap IN WIN32API AS WinAPI_GetProcessHeap
DECLARE INTEGER HeapAlloc IN WIN32API AS WinAPI_HeapAlloc ;
INTEGER, INTEGER, INTEGER
DECLARE INTEGER HeapFree IN WIN32API AS WinAPI_HeapFree ;
INTEGER, INTEGER, INTEGER
DECLARE INTEGER GetOpenFileName IN comdlg32.dll AS WinAPI_GetOpenFileName ;
STRING @
*
*-- Define input strings
LOCAL lnPos as Integer;
,lcFile as String;
,lcFilter as String
lcFile = CHR(0) + REPLICATE(CHR(32), 240) + CHR(0) + CHR(0)
lcFilter = "Text" + CHR(32) ;
+ "*.TXT" + CHR(32) + CHR(0) + CHR(0)
DO WHILE .T.
lnPos = RATC(CHR(32), lcFilter)
IF lnpos > 0
lcFilter = STUFFC(lcFilter, lnpos, 1, CHR(0))
ELSE
EXIT
ENDIF
ENDDO
*
*-- Allocate memory & copy input-strings into memory
LOCAL lnPtrFile as Integer ;
,lnPtrFilter as Integer
*
*-- lnPtrFile
LOCAL lnLenFile as Integer
lnLenFile = LENC(lcFile)
lnPtrFile = WinAPI_HeapAlloc(WinAPI_GetProcessHeap(), 0, lnLenFile)
IF lnPtrFile == 0
? "Error HeapAlloc for lcFile"
CLEAR DLLS
RETURN .F.
ENDIF
SYS(2600, lnPtrFile, lnLenFile, lcFile) && Copy value to memory
*
*-- lnPtrFilter
lnPtrFilter = WinAPI_HeapAlloc(WinAPI_GetProcessHeap(), 0, LENC(lcFilter))
IF lnPtrFilter == 0
WinAPI_HeapFree(WinAPI_GetProcessHeap(), 0, lnPtrFile)
? "Error HeapAlloc for lcFilter"
CLEAR DLLS
RETURN .F.
ENDIF
SYS(2600, lnPtrFilter, LENC(lcFilter), lcFilter) && Copy value to memory
*
*-- Define & fill OPENFILENAME structure
LOCAL lpofn As String
lpofn = BINTOC(N_SIZE_OPENFILENAME, "4RS") ; && DWORD lStructSize
+ BINTOC(0, "4RS") ; && HWND hwndOwner
+ BINTOC(0, "4RS") ; && HINSTANCE hInstance
+ BINTOC(lnPtrFilter, "4RS") ; && LPCTSTR lpstrFilter
+ BINTOC(0, "4RS") ; && LPTSTR lpstrCustomFilter
+ BINTOC(0, "4RS") ; && DWORD nMaxCustFilter
+ BINTOC(1, "4RS") ; && DWORD nFilterIndex
+ BINTOC(lnPtrFile, "4RS") ; && LPTSTR lpstrFile
+ BINTOC(lnLenFile, "4RS") ; && DWORD nMaxFile
+ BINTOC(0, "4RS") ; && LPTSTR lpstrFileTitle
+ BINTOC(0, "4RS") ; && DWORD nMaxFileTitle
+ BINTOC(0, "4RS") ; && LPCTSTR lpstrInitialDir
+ BINTOC(0, "4RS") ; && LPCTSTR lpstrTitle
+ BINTOC(OFN_PATHMUSTEXIST + OFN_FILEMUSTEXIST + OFN_EXPLORER, "4RS") ; && DWORD Flags
+ BINTOC(0, "2RS") ; && WORD nFileOffset
+ BINTOC(0, "2RS") ; && WORD nFileExtension
+ BINTOC(0, "4RS") ; && LPCTSTR lpstrDefExt
+ BINTOC(0, "4RS") ; && LPARAM lCustData
+ BINTOC(0, "4RS") ; && LPOFNHOOKPROC lpfnHook
+ BINTOC(0, "4RS") ; && LPCTSTR lpTemplateName
+ BINTOC(0, "4RS") ; && void * pvReserved
+ BINTOC(0, "4RS") ; && DWORD dwReserved
+ BINTOC(OFN_EX_NOPLACESBAR, "4RS") && DWORD FlagsEx
*!* #if (_WIN32_WINNT >= 0x0500)
*!* #endif // (_WIN32_WINNT >= 0x0500)
*
*-- Call GetOpenFileName
LOCAL lnCode as Integer
lnCode = 0
lnCode = WinAPI_GetOpenFileName(@lpofn)
IF lnCode <> 0
*
*-- Show result
LOCAL lcRetFile as String
lcRetFile = SYS(2600, lnPtrFile, lnLenFile) && Copy value form memory
lnPos = ATC(CHR(0), lcRetFile)
IF lnPos > 0
lcRetFile = LEFTC(lcRetFile, lnPos - 1)
ENDIF
?'Selected file:', lcRetFile
ENDIF
*
* Free memory
WinAPI_HeapFree(WinAPI_GetProcessHeap(), 0, lnPtrFile)
WinAPI_HeapFree(WinAPI_GetProcessHeap(), 0, lnPtrFilter)
CLEAR DLLS
*////////////////////

... здесь решалась задача: избавиться от фильтра: All Files (*.*) в типах открываемых файлов...

Относительно попыток руления с модальными диалогами (у меня в частности, необходимо было давить диалоги-предупреждения об ошибках в скриптах на html-страницах, а также security-предупреждени о левом сертификате при https, при их загрузках через IE control), то подтверждаю, что
- единственное решение которое нашёл: это запустить отдельный/дополнительный процесс, в котором по таймеру (с определённой частотой) искать заголовки модальных окон (на десктопе) и посылать их дочернему окну (кнопке OK) сообщение WM_KEYDOWN с VK_RETURN...
- взаимодействие между основным процессом и этим вспомогательным в VFP 9.0 организовал на Windows сообщениях между окнами (по их дескрипторам)...


------------------
С уважением,
Михаил Дроздов, Пермь, Россия
Ratings: 0 negative/0 positive
Re: GetFile средствами API
Vladimir_Knyr

Сообщений: 1711
Откуда: г. Енисейск
Дата регистрации: 15.12.2003
Михаил, спасиюо!
задача стояла в том чтобы для выбора графических файлов
автоматом открывать окно в виде(рисунок)
не зависимо от настроек винды (можно ввести в настройки программы)

наковырял как мин. 4 способа

но они долгоиграющие

твое подтвержденрие про 2й процесс это как бы самое легкое решение


------------------
хороший код работать будет и обязан, а плохой не жалко.
Ratings: 0 negative/0 positive
Re: GetFile средствами API
Vladimir_Knyr

Сообщений: 1711
Откуда: г. Енисейск
Дата регистрации: 15.12.2003
Ну вот, вроде и получилось , то что и хотелось
1) делаем вот такой EXE файлик - это т.с. и будет вспомогательный процесс,
назовем его к примеру Folder_View0.EXE и положим рядом с нашим будущим EXE
в котором будем использовать наш 2) Get_File()
* Folder_View0
lparameters cTitle,cView
_screen.Visible = .f.
oForm = createobject('ft',m.cTitle , m.cView)
oForm.show()
read events
quit
DEFINE CLASS ft AS form
DoCreate = .T.
Caption = "Form1"
Name = "Form1"
ADD OBJECT timer1 AS timer WITH ;
Top = 168, ;
Left = 36, ;
Height = 23, ;
Width = 23, ;
Interval = 10, ;
Name = "Timer1"
PROCEDURE Init
lparameters cTitle,nView
with thisform.timer1
.addproperty('caption',m.cTitle)
.addproperty('nView',val(m.nView))
endwith
ENDPROC
PROCEDURE timer1.Timer
#define WM_COMMAND 273
Declare integer FindWindow in Win32api string, string
Declare integer FindWindowEx in Win32api integer, integer, string, string
Declare integer SendMessage in user32.dll integer, integer, integer, integer
local fwHandle0 , fwHandle1
m.fwHandle0 = FindWindow(null,This.Caption)
if m.fwHandle0> 0
m.fwHandle1 = FindWindowEx(m.fwHandle0, 0, "SHELLDLL_DefView", 0)
if m.fwHandle1> 0
SendMessage(m.fwHandle1, WM_COMMAND, This.nView, 0)
this.Enabled = .f.
clear events
endif
endif
ENDPROC
ENDDEFINE

2)
* Пример вызова/использования
* folder_view
#define FolderView_LargeIcons 28713
#define FolderView_SmallIcons 28714
#define FolderView_List 28715
#define FolderView_Details 28716
#define FolderView_Thumbnails 28717
#define FolderView_Tiles 28718
*!* sf = sys(5)+addbs(curdir())+'folder_view0.exe title ' + transform(FolderView_SmallIcons)
*!* run /N &sf
*!* getfile("JPG","text","buttontext",0,"title")
*!* return
aaa = get_file(FolderView_Thumbnails,'JPG','text','buttontext',0,'&#212;&#232;&#227;&#224;')
messagebox(aaa)
function get_file && GETFILE([cFileExtensions] [, cText] [, cOpenButtonCaption] [, nButtonType] [, cTitleBarCaption])
lparameters nFolderView, cFileExtensions, cText, cOpenButtonCaption, nButtonType, cTitleBarCaption
local nParam , cResult , sf
m.cResult = ''
m.nParam = parameters()
if m.nParam = 0
m.cResult = getfile()
else
if m.nParam > 6
messagebox('&#205;&#229; &#239;&#240;&#224;&#226;&#232;&#235;&#252;&#237;&#238;&#229; &#247;&#232;&#241;&#235;&#238; &#224;&#240;&#227;&#243;&#236;&#229;&#237;&#242;&#238;&#226; &#244;&#243;&#237;&#234;&#246;&#232;&#232;',0,'Get_File()')
else
m.sf = sys(5)+addbs(curdir())+'folder_view0.exe '
m.sf = m.sf+iif(m.nParam<6,'open',m.cTitleBarCaption)+' '+transform(m.nFolderView)
run /N &sf
do case
case m.nParam = 1
m.cResult = getfile()
case m.nParam = 2
m.cResult = getfile(m.cFileExtensions)
case m.nParam = 3
m.cResult = getfile(m.cFileExtensions,m.cText)
case m.nParam = 4
m.cResult = getfile(m.cFileExtensions,m.cText,m.cOpenButtonCaption)
case m.nParam = 5
m.cResult = getfile(m.cFileExtensions,m.cText,m.cOpenButtonCaption,m.nButtonType)
case m.nParam = 6
m.cResult = getfile(m.cFileExtensions,m.cText,m.cOpenButtonCaption,m.nButtonType,m.cTitleBarCaption)
endcase
endif
endif
return m.cResult


------------------
хороший код работать будет и обязан, а плохой не жалко.
Ratings: 0 negative/0 positive
Re: GetFile средствами API
rvc44
Автор

Сообщений: 2211
Откуда: Тамбов
Дата регистрации: 06.12.2005
2Vladimir_Knyr

1. Да, Владимир, Ваше решение работает и также имеет право на жизнь!
Добавлю лишь ряд замечаний, что в Folder_View0.prg, после _screen.Visible = .F. можно еще добавить:
If Empty(cTitle) OR Empty(cView)
Return .F.
EndIf
на случай, если полученный EXE-файл кто-то из юзеров попробует запустить на исполнение (чтобы не появилась ошибка), да и хорошо бы добавить в проект из одного PRG-файла, файл config.fpw, содержащий строки:
RESOURCE=OFF
SCREEN=OFF
чтобы не было мигания при переключении _screen.Visible = .F.
Но лучше бы, вообще, folder_view0.exe оформить в виде DLL-файла, т.к. все-таки EXE-файлы чаще подвержены атакам вирусов. Я лично наблюдал разрушение вирусом своего файла у одного из клиентов...

2. Вообще-то задача, поставленная Владимиром, уже давно решена, причем намного проще и двумя способами! Хотя на Vista лично я не проверял ;) , но все должно работать!
Способ №1 от Cesar Chalom:
oShell = CREATEOBJECT("Wscript.Shell")
oShell.SendKeys("{TAB}{TAB}{TAB}{TAB}{TAB}{DOWN}{DOWN}{DOWN}{DOWN}{ENTER}")
GETPICT()

Способ №2 (более короткий) от Christophe Chenavier:
oShell = CREATEOBJECT("Wscript.Shell")
oShell.SendKeys("+{TAB}+{F10}{DOWN}{ENTER}{ENTER}") && "+" это Shift
GETPICT()

Все коды клавиш для SENDKEYS можно найти здесь:
h_t_t_p://msdn2.microsoft.com/en-us/library/system.windows.forms.sendkeys(vs.71).aspx

P.S. M$, атакованная этим вопросом программистами рекомендует, правда БЕЗ ГАРАНТИЙ, на VB делать следующее:
Sub InsertPicture()
' InsertPicture Macro
' Inserts a picture from a graphics file.
' Sets the View to (D)etail with SendKeys.
' View choices [change last Sendkey Letter].
' D - (D)etails view
' G - Lar(g)e Icon view
' L - (L)ist view
' M - S(m)all Icon view
' R - P(r)operties View
' V - Pre(v)iew View
' T - (T)humbnails View
SendKeys ("%L{LEFT}D")
Application.Dialogs(wdDialogInsertPicture).Show
End Sub

Подытоживая тему, возникает вопрос, а нафига тогда вообще в Фоксе функция:
= GETPICT("JPG", "&Имя файла", "&Открыть")
По законам логики у нее должен быть 4-й (недокументированный) параметр nFolderView...
Хоть бы, чтоли в VFP9 SP3 его включили! Иначе, каково ее отличие от GETFILE()?
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 44 (Гостей: 44)

© 2000-2024 Fox Club 
Яндекс.Метрика