Visual Studio 2012 - 2 błędy: As Any oraz ByVal


(sexy69bis) #1

W VB6..jest OK

Public Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Boolean

Public Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" (lpFileName As Any, lpFindFileData As WIN32_FIND_DATA) As Long

Public Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Boolean


Public Type FILETIME

   dwLowDateTime As Long

   dwHighDateTime As Long

End Type


Public Type WIN32_FIND_DATA

   Atrybuty As Long

   ftCreationTime As FILETIME

   ftLastAccessTime As FILETIME

   ftLastWriteTime As FILETIME

   nFileSizeHigh As Long

   nFileSizeLow As Long

   dwReserved0 As Long

   dwReserved1 As Long

   nazwa(260) As Byte

End Type


Private WFD As WIN32_FIND_DATA


Sub Main()

   Dim uchwyt As Long

   Dim nazwa As String

   Katalog = "g:\JpgNiesprawdzone\"

   uchwyt = FindFirstFile(ByVal StrPtr(Katalog & "*.jpg"), WFD)


   Do: nazwa = Left(WFD.nazwa, InStr(WFD.nazwa, Chr(0)) - 1)

      NR = NR + 1

   Loop While FindNextFile(uchwyt, WFD)

End Sub

to samo po małej przeróbce na Visual Studio 2012 Express '_________________________________________________________________________

Module mainModule

   Public Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Boolean

   Public Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" (lpFileName As Any, lpFindFileData As WIN32_FIND_DATA) As Long

   Public Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Boolean


   Public Structure FILETIME

      Dim dwLowDateTime As Long

      Dim dwHighDateTime As Long

   End Structure


   Public Structure WIN32_FIND_DATA

      Dim Atrybuty As Long

      Dim ftCreationTime As FILETIME

      Dim ftLastAccessTime As FILETIME

      Dim ftLastWriteTime As FILETIME

      Dim nFileSizeHigh As Long

      Dim nFileSizeLow As Long

      Dim dwReserved0 As Long

      Dim dwReserved1 As Long
 Dim nazwa As String

   End Structure


   Private WFD As WIN32_FIND_DATA


   Sub Main()

      Dim uchwyt As Long

      Dim Katalog, NR

      Dim nazwaPliku

      Katalog = "g:\JpgNiesprawdzone\"

   uchwyt = FindFirstFile(ByVal StrPtr(Katalog & "*.jpg"), WFD)'<- "ByVal" Oczekiwano wyrażenia.


      Do : nazwaPliku = Left(WFD.nazwa, InStr(WFD.nazwa, Chr(0)) - 1)

         NR = NR + 1

      Loop While FindNextFile(uchwyt, WFD)

   End Sub


End Module

'-------------

2 Błędy

Element „As Any" nie jest obsługiwany w instrukcjach „Declare".

"ByVal" Oczekiwano wyrażenia.

Proszę o pomoc w usunięciu tych błędów.


(Pablo_Wawa) #2

Zerknąłem tak na szybko:

Błąd pierwszy - nie ma (chyba) typu Any (jest Variant), ale tam trzeba użyć typu String - mowa o deklaracji 2 funkcji.

Błąd drugi - chyba fałszywy alarm wynikający z poprzedniego błędu, ale tak czy inaczej brakuje ByVal w deklaracji 2 funkcji, która powinna wyglądać tak:

Public Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long

(sexy69bis) #3

po zamianie "lpFileName As Any" na: "ByVal lpFileName" nadal pozostaje jeszcze błąd drugi.


(Pablo_Wawa) #4

A nie masz informacji, w której linii on występuje (podaj jej kod)?


(mr-owl) #5

Witam,

Zobacz co podpowiada Ci www.pinvoke.net

http://www.pinvoke.net/default.aspx/kernel32.FindClose

http://www.pinvoke.net/default.aspx/ker ... dFirstFile

http://www.pinvoke.net/default.aspx/ker ... ndNextFile

Pozdrawiam,

mr-owl


(sexy69bis) #6

teraz pierwszy błąd po zamianie "lpFileName As Any" na: "ByVal lpFileName", podkreślone jest lpFileName

z opisem: Jeśli którekolwiek z parametrów mają jawnie określone typy, to wszystkie parametry muszą mieć jawnie określone typy.

drugi błąd:- "ByVal" w: uchwyt = FindFirstFile(ByVal StrPtr(Katalog & "*.jpg"), WFD)

podkreślony z opisem: Oczekiwano wyrażenia


(Pablo_Wawa) #7

Co do problemów na początku (teraz miałem czas i przejrzałem dokładniej podany kod), to drugi błąd (ten od ByVal) jest dlatego, że typy parametrów (ByVal, ByRef) podaje się tylko w deklaracji funkcji, a nie przy jej wywołaniu. Usuń wiec zbędny ByVal z kodu:

uchwyt = FindFirstFile(StrPtr(Katalog & "*.jpg"), WFD) '<-i będzie dobrze.

(sexy69bis) #8

uchwyt = FindFirstFile(StrPtr(Katalog & "*.jpg"), WFD)

błąd przenosi się na StrPtr z opisem:

Nie zadeklarowano elementu „StrPtr". Może on być

niedostępny z powodu jego poziomu ochrony.

Wygeneruj szkielet metody do 'StrPtr' w

Projectl.mainModule'

Wygeneruj szkielet właściwości do 'StrPtr' w

'Projectl.mainModule'


(Pablo_Wawa) #9

To wywal tę konwersję (StrPtr), sprawdź czy tak będzie dobrze:

uchwyt = FindFirstFile(Katalog & "*.jpg", WFD)

(sexy69bis) #10

uchwyt = FindFirstFile(Katalog & "*.jpg", WFD)

drugi błąd zniknął ale..

dalej pierwszy błąd po zamianie "lpFileName As Any" na: "ByVal lpFileName", zamiast Any podkreślone jest lpFileName

z opisem: Jeśli którekolwiek z parametrów mają jawnie określone typy, to wszystkie parametry muszą mieć jawnie określone typy.


(Pablo_Wawa) #11

ale ja napisałem łącznie co innego (we wcześniejszych poradach):

zamiana "lpFileName As Any" na "ByVal lpFileName As String"

patrz porada z 22.07.2013 (Pn) 20:33.


(sexy69bis) #12

poprawka


(Pablo_Wawa) #13

A możesz rozwinąć myśl?


(sexy69bis) #14

właśnie sprawdzam

-- Dodane 23.07.2013 (Wt) 13:14 --

kod wygląda teraz tak:

Module mainModule

   Public Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Boolean

   Public Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long

   'Public Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileW" (lpFileName As Any, lpFindFileData As WIN32_FIND_DATA) As Long

   Public Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Boolean


   Public Structure FILETIME

      Dim dwLowDateTime As Long

      Dim dwHighDateTime As Long

   End Structure


   Public Structure WIN32_FIND_DATA

      Dim Atrybuty As Long

      Dim ftCreationTime As FILETIME

      Dim ftLastAccessTime As FILETIME

      Dim ftLastWriteTime As FILETIME

      Dim nFileSizeHigh As Long

      Dim nFileSizeLow As Long

      Dim dwReserved0 As Long

      Dim dwReserved1 As Long
 Dim nazwa As String

   End Structure


   Private WFD As WIN32_FIND_DATA


   Sub Main()

      Dim uchwyt As Long

      Dim Katalog, NR&

      Dim nazwaPliku

      Katalog = "g:\JpgNiesprawdzone\"

      'uchwyt = FindFirstFile(ByVal StrPtr(Katalog & "*.jpg"), WFD)

      uchwyt = FindFirstFile(Katalog & "*.jpg", WFD)


      Do : nazwaPliku = Left(WFD.nazwa, InStr(WFD.nazwa, vbNullChar) - 1)

         NR = NR + 1

      Loop While FindNextFile(uchwyt, WFD)

   End Sub


End Module

Przy wierszu 32: uchwyt = FindFirstFile(Katalog & "*.jpg", WFD)

pojawia się teraz informacja:

Additional Information: Wywołanie funkcji PInvoke Projectl!

Projectl.mainModule::FindFirstFile' zachwiało równowaga stosu. Prawdopodobna

przyczyna to niedopasowanie zarządzanego podpisu funkcji PInvoke i

niezarządzanego podpisu docelowego. Sprawdź, czy konwencja wywołania i

parametry podpisu funkcji PInvoke pasują do niezarządzanego podpisu docelowego.


(Pablo_Wawa) #15
  1. Co oznacza znak " &" po nazwie zmiennej - mam na myśli wiersz

    Dim Katalog, NR&

Nie kojarzę tego znaczenia, usuń może ten znak i zobacz czy pomogło. 2. Spróbuj na sztywno wpisać

uchwyt = FindFirstFile("g:\JpgNiesprawdzone\*.jpg", WFD)

na razie tak testowo - może to pomoże?


(sexy69bis) #16

1.Jak w oknie odpowiedzi ten znak umieszczę w kodzie

&

to znak jest OK, a jak bez kodu to wygląda tak & Okno odpowiedzi bez wstawki początek i koniec kodu zmienia ten znak. 2.

uchwyt = FindFirstFile("g:\JpgNiesprawdzone\*.jpg", WFD)

to same objawy jak przy

uchwyt = FindFirstFile(Katalog & "*.jpg", WFD)

(Pablo_Wawa) #17

Czy nie jest tak, że przy podawaniu ścieżek (katalogów) należy znak "\" podwajać: "\" bo jeden to prefiks znaku specjalnego (np. "\n" to nowy wiersz). CHYBA, bo ja nie programuję w VB i nie mam go by to sprawdzać. Może w Basicu nie trzeba...


(sexy69bis) #18

1 podwójny i 2 podwójne znaki nic nie zmieniają.

Jak pisałem na początku postu, w Visual Basic 6 ten kod działa, ale nie mogę go przerobić na Visual Basic 2012


(Pablo_Wawa) #19

Już wiem, gdzie masz błąd - przejrzałem dokumentację i sprawdziłem u siebie w Excelu (VBA) na Windows XP:

Błąd polega na braku pola dla skróconej nazwy pliku w WIN32_FIND_DATA - musisz na końcu ją zadeklarować (ja nazwałem to pole short):

Public Type WIN32_FIND_DATA

   Atrybuty As Long

   ftCreationTime As FILETIME

   ftLastAccessTime As FILETIME

   ftLastWriteTime As FILETIME

   nFileSizeHigh As Long

   nFileSizeLow As Long

   dwReserved0 As Long

   dwReserved1 As Long

   nazwa(260) As Byte

   short(14) As Byte

End Type

Dodatkowo ja musiałem zmienić nazwę "FindFirstFileW" na "FindFirstFileA" w 2 miejscach na początku - i zadziałało (być może w Windows Vista/7 nie trzeba tego robić).

FindFirstFileW (Unicode)

FindFirstFileA (ANSI)


(sexy69bis) #20
Module mainModule

   Public Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Boolean

   Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long

   Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal FindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long


   Public Structure FILETIME

      Dim dwLowDateTime As Long

      Dim dwHighDateTime As Long

   End Structure


   Public Structure WIN32_FIND_DATA

      Dim Atrybuty As Long

      Dim ftCreationTime As FILETIME

      Dim ftLastAccessTime As FILETIME

      Dim ftLastWriteTime As FILETIME

      Dim nFileSizeHigh As Long

      Dim nFileSizeLow As Long

      Dim dwReserved0 As Long

      Dim dwReserved1 As Long
 Dim nazwa As String
 Dim cAlternate As String

   End Structure


   Private WFD As WIN32_FIND_DATA


   Sub Main()

      Dim uchwyt As Long

      Dim NR& ', Katalog

      Dim nazwaPliku

      'Katalog = "g:\JpgNiesprawdzone\"

      'uchwyt = FindFirstFile(ByVal StrPtr(Katalog & "*.jpg"), WFD)

      'uchwyt = FindFirstFile(Katalog & "*.jpg", WFD)

      uchwyt = FindFirstFile("g:\JpgNiesprawdzone\*.jpg", WFD)


      Do : nazwaPliku = Left(WFD.nazwa, InStr(WFD.nazwa, vbNullChar) - 1)

         NR = NR + 1

      Loop While FindNextFile(uchwyt, WFD)

   End Sub


End Module

Po zmianie 2x FindFirstFileW na FindFirstFileA teraz w polu

uchwyt = FindFirstFile("g:\JpgNiesprawdzone*.jpg", WFD) , pisze że:

"Additional information: Nastąpiła próba odczytu lub zapisu pamięci chronionej.

Często wskazuje to, że inna pamięć jest uszkodzona."

short(14) As Byte, to należy do VB6, ale bez tego wpisu też ten kod działa

W VS2012 wpisałem: Dim cAlternate As String

ja też używam Windows 7 Ultimate 64-bit