Results 1 to 13 of 13

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date: Nov:2006
    Location: varna
    Posts: 10

    Unhappy Ïðîáëåì ñ UNICODE FILE PATH

    Çäðàâåéòå !!!

    Èìàì ñëåäíèÿ íåðàçðåøèì çà ìåí ïðîáëåì :

    Îïèòâàì ñå äà ñâàëÿ ôàéë (.exe, .jpg .gif) îò Web site è äà ãî çàïèøà.
    Ïðîãðàìàòà ñè âúðâè äîáðå ñ èçêëþ÷åíèå íà ñëó÷àèòå â êîèòî ñå îïèòâàì äà çàïàçÿ èçòåãëåíèÿò ôàéë â FILE PATH, êîéòè ñúäúðæà ñèìâîëè ðàçëè÷íè îò àíãëèéñêèòå.
    Ãðåøêàòà êîÿòî ïîëó÷àâàì ïî âðåìå íà èçïúëíåíèå å :

    "Run-time error '52': Bad file name or number" â òîçè ðåä : "Open DestFile For Binary Access Write As #1"

    Äî êîëêîòî ñúì çàïîçíàò ïðè÷èíàòà å, ÷å VB êîíâåðòèðà FILE PATH â ANSI.

    Êîäúò çà çàïèñ êîéòî ïîëçâàì å :

    Code:
    Case icResponseCompleted  ' 12
                Dim bDone As Boolean: bDone = False
                Dim tempArray() As Byte
                            
                Open DestFile For Binary Access Write As #1
                 
                vtData = Inet1.GetChunk(1024, icByteArray)
                DoEvents
            
                If Len(vtData) = 0 Then
                    bDone = True
                End If
            
                Do While Not bDone
                    tempArray = vtData
                    Put #1, , tempArray
                            
                    ' Get next chunk.
                    vtData = Inet1.GetChunk(1024, icByteArray)
                    DoEvents
                                    
                    If Len(vtData) = 0 Then
                        bDone = True
                    End If   
                    
                Loop
                Close #1
    Íÿêîé ñáëúñêâàë ëè ñå å ñ ïîäîáåí ïðîáëåì è óñïÿâàë ëè å äà ãî ðåøè ?

  2. #2
    Áåëûé è ïóøèñòûé Bombera's Avatar
    Join Date: Jul:2001
    Location: Êàçàíëúê 4EVA
    Posts: 13,833
    Òðÿáâà äà íè ïîêàæåø êàê ïúëíèø DestFile ñúñ ñúäúðæàíèå. Â òîçè îòêúñ íå ñå âèæäà è ãðåøêàòà èçãëåæäà ñúâñåì íà ìÿñòî.
    Åäèí îò î÷åâèäíèòå íà÷èíè äà ãî çàîáèêîëèø ïðîáëåìà ñ Óíèêîä èìåíàòà å, àêî ïîëçâàø Win32 API ôóíêöèèòå ñà ðàáîòà ñ ôàéëîâå.
    Last edited by Bombera; 16th May 2011 at 15:10.
    EVGA X299 FTW K|i9-7960X@4.7|4x8 Patriot Viper Steel 4000|GTX 1660 Ti|970 EVO 1 TB|Seasonic Focus GX-1000|Xigmatek Elysium|Êèëî è ïîëîâèíà âîäà
    Rampage IV Extreme BE|E5-1680v2@4.7|4x4 HyperX 1866|Cougar Aqua 240|GTX 1050 Ti|970 EVO 1/4 TB|CM 850 SilentPro|HAF-X|Áåç èñòèíñêî âîäíî

  3. #3
    Registered User
    Join Date: Nov:2006
    Location: varna
    Posts: 10
    Áëàãîäàðÿ çà áúðçèÿ îòãîâîð

    Àç ìèñëÿ, ÷å ñå âèæäà êàê ïúëíÿ DestFile ïúðâî ñ Open è ïîñëå ñ Put, îñâåí àêî íåùî íå ñúì òå äîðàçáðàë. Äðóãè ìàíèïîëàöèè íå ïðàâÿ âúðõó ôàéëà.
    Êîëêîòî äî DestFile, òîé å äà ðå÷åì "c:\test\ïðîáà\ôàéë.jpg" êàòî ñòðèíãà å â unicode ôîðìàò. Ñ ìîäèôèöèðàíà âåðñèÿ (Unicode) íà MsgBox, DestFile ñòðèíãà ñå ïîêàçâà ïðàâèëíî ñ òîçè ðåä :
    Code:
    Msgbox DestFile
    Last edited by vlado_sfi; 20th May 2011 at 15:50.

  4. #4
    Áåëûé è ïóøèñòûé Bombera's Avatar
    Join Date: Jul:2001
    Location: Êàçàíëúê 4EVA
    Posts: 13,833
    Çíà÷è Open íå ðàáîòè ñ Unicode ñòðèíãîâå âåðîÿòíî, êàêúâòî êàçâàø, ÷å ñúäúðæà DestFile. Àêî çàäàäåø ANSI ñòðèíã íà DestFile, âñè÷êî ðàáîòè ëè?
    Òèÿ ôàéëîâå, êîèòî ñå îïèòâàø äà îòâîðèø, êîèòî èìàò ñòðàííè ñèìâîëè, äà íå ñà ïðàâåíè ïîä 95 èëè 98? Èëè íà êîìïþòúð ñ ÔëåêñÒàéï?
    EVGA X299 FTW K|i9-7960X@4.7|4x8 Patriot Viper Steel 4000|GTX 1660 Ti|970 EVO 1 TB|Seasonic Focus GX-1000|Xigmatek Elysium|Êèëî è ïîëîâèíà âîäà
    Rampage IV Extreme BE|E5-1680v2@4.7|4x4 HyperX 1866|Cougar Aqua 240|GTX 1050 Ti|970 EVO 1/4 TB|CM 850 SilentPro|HAF-X|Áåç èñòèíñêî âîäíî

  5. #5
    Registered User
    Join Date: Nov:2006
    Location: varna
    Posts: 10
    Àêî ïîëçâàì ANSI ìè èçëèçàò ñèìâîëè îò ðîäà íà n ñ âúëíè÷êà íàä íåãî c ñ çàïåòàÿ îò äîëó , ïîíåæå ðåãèîíàëíèòå íàñòðîéêè ñúì ãè îñòàâèë ïî ïîäðàçáèðàíå (óìèøëåíî òúé êàòî ïðè FILE PATH ñ íåìñêè èëè íÿíàêâè äðóãè ñèìâîëè ïàê äàâà ãðåøêà). Àêî çà "Language for non-Unicode programs" ñúì çàäàë Bulgarian, âñè÷êî ñè å íîðìàëíî è íå äàâà ãðåøêà. Íî çà äà ìîæå ïðîãðàìàòà äà ðàáîòè íîðìàëíî ñúñ âñÿêàêâè ðåãèîíàëíè íàñòðîéêè å íåîáõîäèìî äà ïîëçâàì Unicode ôóíêöèè êàêâèòî ñà API ôóíêöèèòå WriteFile è CreateFile, íî íå óñïÿâàì äà ãî íàïðàâÿ ñ òÿõ.

    Êîëêîòî äè ôàéëîâåòå òå ñå ñúçäàâàò îò òîçè ðåä ïî âðåìå íà èçïúëíåíèå íà ïðîãðàìàòà:
    Open DestFile For Binary Access Write As #1
    Last edited by vlado_sfi; 16th May 2011 at 17:16.

  6. #6
    Áåëûé è ïóøèñòûé Bombera's Avatar
    Join Date: Jul:2001
    Location: Êàçàíëúê 4EVA
    Posts: 13,833
    ßñíî å êàêâî ñòàâà çíà÷è.
    Óíèêîä ôóíêöèèòå ñà CreateFileW è WriteFileW. Àêî òðÿáâà äà ãè èìïîðòàø îò DLL-a, Kernel32.dll, òåçè èìåíà ùå òðÿáâà äà ïîëçâàø. Èìåíàòà áåç W íàêðàÿ ñà ANSI âåðñèèòå. Îñòàâà äà ñå íàó÷èø êàê äà ðàáîòèø ñ Óíèêîä ñòðèíãîâå â Áåéñèê, êàê äà òðàíñëèðàø îò ANSI â Óíèêîä ñ MutiByteToWideChar è WideCharToMultiByte, èëè àêî èìà ïî-ëåñåí íà÷èí â ñàìèÿ VB. Ïðîáëåìúò ïðè òåá å, ÷å àêî õàðäêîðíåø èìåòî â êîäà ñè êàòî ANSI ñòðèíã, òî çíà÷è ðàçëè÷íè íåùà ïðè ðàçëè÷íè ðåãèîíàëíè íàñòðîéêè. Ïî ïðèíöèï, ôàéëîâèòå èìåíà íà äèñêà ñå ïàçÿò â Óíèêîä, òàêà ÷å, àêî ïîëçâàø Óíèêîä ñòðèíã, çà äà ãè âèêàø, ïðîáëåìúò ùå ñå ðåøè. Íå çíàÿ îáà÷å êàê ñå äåôèíèðàò è êàê ñå èçïèñâàò ÷èñòî ñèíòàêòè÷íî òèÿ íåùà âúâ VB.
    EVGA X299 FTW K|i9-7960X@4.7|4x8 Patriot Viper Steel 4000|GTX 1660 Ti|970 EVO 1 TB|Seasonic Focus GX-1000|Xigmatek Elysium|Êèëî è ïîëîâèíà âîäà
    Rampage IV Extreme BE|E5-1680v2@4.7|4x4 HyperX 1866|Cougar Aqua 240|GTX 1050 Ti|970 EVO 1/4 TB|CM 850 SilentPro|HAF-X|Áåç èñòèíñêî âîäíî

  7. #7
    Registered User
    Join Date: Nov:2006
    Location: varna
    Posts: 10
    Áëàãîäàðÿ çà îòãîâîðà !
    Àç ñòèãíàõ äî ñëåäíàòà ñèòóàöèÿ.
    Òåãëÿ ôàéëà è ãî òðóïàì â ìàñèâ :
    Code:
    Case icResponseCompleted  ' 12
    
    Dim tempArray() As Byte
    Dim vtData As Variant
    Dim bDone As Boolean: bDone = False
    
    ' Get first chunk.
                vtData = Inet1.GetChunk(1024, icByteArray)
                DoEvents
            
                If Len(vtData) = 0 Then
                    bDone = True
                End If
            
                Do While Not bDone
    
                    tempArray = vtData
                      
                    ' Get next chunk.
                    vtData = Inet1.GetChunk(1024, icByteArray)
                    DoEvents
                                    
                    If Len(vtData) = 0 Then
                        bDone = True
                    End If
                                                    
                Loop
                Call WriteBytesToFile(DestFile , tempArray)
    Ñëåä òîâà ïîäàâàì ìàñèâà íà ôóíêöèÿòà WriteBytesToFile :

    Code:
    Public Function WriteBytesToFile(Filename As String, TheData() As Byte, _
      Optional NoOverwrite As Boolean = False) As Boolean
    
    
    Dim lHandle As Long
    Dim lSuccess As Long
    Dim lBytesWritten As Long, lBytesToWrite As Long
    If NoOverwrite = True And Dir(Filename) <> "" Then Exit Function
    lBytesToWrite = UBound(TheData) - LBound(TheData)
             
    lHandle = CreateFile(StrPtr(Filename), GENERIC_WRITE Or GENERIC_READ, _
                         0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
    
    If lHandle <> INVALID_HANDLE_VALUE Then
       lSuccess = WriteFile(lHandle, TheData(0), _
                            lBytesToWrite, lBytesWritten, 0) <> 0
       If lSuccess <> 0 Then
          lSuccess = FlushFileBuffers(lHandle)
          lSuccess = CloseHandle(lHandle)
       End If
    End If
    ErrorHandler:
    WriteBytesToFile = lSuccess <> 0
    End Function
    È òàêà ôàéëúò ñå çàïèñâà, íî å ñ ïî ìàëúê ðàçìåð 768 bytes, à ðåàëíèÿò ðàçìåð å 3992 Kbytes.
    Íÿêîé çíàå ëè çàùî ñå ïîëó÷àâà òàêà è êàê ìîæå äà ïîïðàâè ?

  8. #8
    philosophus duratea icaci's Avatar
    Join Date: Oct:2006
    Location: Aachen
    Posts: 2,698
    Òðÿáâà äà äîáàâÿø vtData â êðàÿ íà tempArray, à íå äà ìó ãî ïðèñâîÿâàø. Òèÿ 768 áàéòà ñà âñúùíîñò ïîñëåäíèÿò áëîê îò ñâàëÿíåòî.
    Internet - it doesn't make you stupid, it just makes your stupidity more accessible to others

  9. #9
    Registered User
    Join Date: Nov:2006
    Location: varna
    Posts: 10
    Àç ïðîáâàõ òîâà íî ìè äàâà ãðåøêà "Run-time error '13': Type Mismatch".
    Ïî òîçè íà÷èí :


    Code:
    Case icResponseCompleted  ' 12
    
    Dim tempArray() As Byte
    Dim vtData As Variant
    Dim bDone As Boolean: bDone = False
    Dim i As Long
    
    ' Get first chunk.
                vtData = Inet1.GetChunk(1024, icByteArray)
                DoEvents
            
                If Len(vtData) = 0 Then
                    bDone = True
                End If
            
                i = -1
                
                Do While Not bDone
                    i = i + 1
                    ReDim Preserve tempArray(i + 1) As Byte
                    tempArray(i) = vtData
                      
                    ' Get next chunk.
                    vtData = Inet1.GetChunk(1024, icByteArray)
                    DoEvents
                                    
                    If Len(vtData) = 0 Then
                        bDone = True
                    End If
                                                    
                Loop
                Call WriteBytesToFile(DestFile , tempArray)


    --------- Äîáàâåíî â 14:16 --------- Ïðåäèøíî ìíåíèå: â÷åðà â 15:09 ---------

    Íÿêîé ìîæå ëè äà ìè êàæå çàùî ñå ïîëó÷àâà òàçè ãðåøêà ?

  10. #10
    Registered User mitkohr's Avatar
    Join Date: Jul:2001
    Posts: 1,361
    çàùî íå ãî íàïðàâèø òàêà:
    Code:
    Case icResponseCompleted  ' 12
    
    Dim tempArray() As Byte
    Dim vtData As Variant
    Dim bDone As Boolean: bDone = False
    
    Do While Not bDone
      vtData = Inet1.GetChunk(1024, icByteArray)
      if Len(vtData) = 0 then 
        bDone = True
      else 
        tempArray = vtData
        Call WriteBytesToFile(DestFile , tempArray)
      end if
    Loop
    êàòî ñëîæèø è èçðè÷íî äà ñå äîáàâÿ êúì êðàÿ íà ôàèëà:
    Code:
    Public Function WriteBytesToFile(Filename As String, TheData() As Byte, _
      Optional NoOverwrite As Boolean = False) As Boolean
    
    
    Dim lHandle As Long
    Dim lSuccess As Long
    Dim lBytesWritten As Long, lBytesToWrite As Long
    If NoOverwrite = True And Dir(Filename) <> "" Then Exit Function
    lBytesToWrite = UBound(TheData) - LBound(TheData)
             
    lHandle = CreateFile(StrPtr(Filename), GENERIC_WRITE Or FILE_APPEND_DATA, _
                         0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
    
    If lHandle <> INVALID_HANDLE_VALUE Then
       lSuccess = WriteFile(lHandle, TheData(0), _
                            lBytesToWrite, lBytesWritten, 0) <> 0
       If lSuccess <> 0 Then
          lSuccess = FlushFileBuffers(lHandle)
          lSuccess = CloseHandle(lHandle)
       End If
    End If
    ErrorHandler:
    WriteBytesToFile = lSuccess <> 0
    End Function
    Gigabyte X570 Aorus Elite, AMD Ryzen 7 5800X@PBO+200, Noctua NH-D15, 2x16GB G.Skill F4-3600C17D-32GTZR, Palit GeForce RTX 4070 Ti GameRock Classic, 2x Sandisk Extreme II 240GB (not in RAID)+WD 320GB AAKS + WD40EZRZ + Toshiba X300 6GB, Cooler Master HAF 922, CORSAIR 750W CX

  11. #11
    Registered User
    Join Date: Nov:2006
    Location: varna
    Posts: 10
    Áëàãîäàðÿ çà áúðçèÿ îòãîâîð

    Ïðîáâàõ ãî, íî ìè äàâà ãðåøêà "Run-time error '35758': Unable to retrieve data" íà òîçè ðåä vtData = Inet1.GetChunk(1024, icByteArray) .
    Âúïðåêè òîâà çàïèñâà ôàéë, íî å ñ ðàçìåð 1023 bytes.
    Äåêëàðàöèèòå êîèòî ïîëçâàì ñà :

    Code:
    Private Const GENERIC_WRITE = &H40000000
    Private Const GENERIC_READ = &H80000000
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const CREATE_ALWAYS = 2
    Private Const OPEN_ALWAYS = 4
    Private Const INVALID_HANDLE_VALUE = -1
    Private Const FILE_APPEND_DATA = &H4
    
    Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
       lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, _
       lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
    
    Private Declare Function CloseHandle Lib "kernel32" ( _
      ByVal hObject As Long) As Long
    
    Private Declare Function WriteFile Lib "kernel32" ( _
      ByVal hFile As Long, lpBuffer As Any, _
      ByVal nNumberOfBytesToWrite As Long, _
      lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
    
    Private Declare Function CreateFile Lib "kernel32" _
      Alias "CreateFileW" (ByVal lpFileName As Long, _
      ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _
      ByVal lpSecurityAttributes As Long, _
      ByVal dwCreationDisposition As Long, _
      ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) _
      As Long
    Last edited by vlado_sfi; 20th May 2011 at 14:25.

  12. #12
    Registered User
    Join Date: Nov:2006
    Location: varna
    Posts: 10
    Áëàãîäàðÿ íà âñè÷êè çà óñèëèÿòà êîèòî ïîëîæèõòå äî ñåãà
    Ïîðàáîòèõ ìàëêî íàä êîäà è ñåãà ôàéëúò ñå èçòåãëÿ, íî íå ñå îòâàðÿ. Ìàëêî ñúì ñå èç÷åðïàë îò êúì èäåè è ìîëÿ çà ñúâåò .
    Òîâà å êîäúò:

    Code:
    Private Sub dn_btn_Click()
    
    Inet1.Execute "http://leselevesfrancais.files.wordpress.com/2008/10/eiffel-tower-picture.jpg", "GET"
    
    End Sub
    
    Private Sub Inet1_StateChanged(ByVal State As Integer)
    
    Dim vtData As Variant
    Dim tempArray() As Byte
    Dim DestFile As String: DestFile = "C:\test.jpg"
    Dim bDone As Boolean: bDone = False
    Dim curByte As Long: curByte = 0
    
        Select Case State
            
      
        Case icResponseCompleted  ' 12
                 
            Call CreateFileApi(DestFile)
    
            Do While Not bDone
                vtData = Inet1.GetChunk(1024, icByteArray)
                If Len(vtData) = 0 Then
                    bDone = True
                    Call WriteBytesToFile(DestFile, tempArray, curByte, , True)
                Else
                    tempArray = vtData
                    Call WriteBytesToFile(DestFile, tempArray, curByte)
                    curByte = curByte + ((UBound(tempArray) - LBound(tempArray) + 1))
                End If
            Loop
                
        Case icError '11
            MsgBox Inet1.ResponseInfo, vbCritical, "ERROR!"
                
        End Select
    End Sub
    Code:
    Option Explicit
    
    Dim lHandle As Long
    Private Const GENERIC_WRITE = &H40000000
    Private Const GENERIC_READ = &H80000000
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const CREATE_ALWAYS = 2
    Private Const OPEN_ALWAYS = 4
    Private Const INVALID_HANDLE_VALUE = -1
    Private Const FILE_APPEND_DATA = &H4
    
    
    Private Declare Function CloseHandle Lib "kernel32" ( _
      ByVal hObject As Long) As Long
    
    Private Declare Function WriteFile Lib "kernel32" ( _
      ByVal hFile As Long, lpBuffer As Any, _
      ByVal nNumberOfBytesToWrite As Long, _
      lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
    
    Private Declare Function CreateFile Lib "kernel32" _
      Alias "CreateFileW" (ByVal lpFileName As Long, _
      ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _
      ByVal lpSecurityAttributes As Long, _
      ByVal dwCreationDisposition As Long, _
      ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) _
      As Long
    Code:
    Public Function WriteStringToFile(Filename As String, ByVal TheData As String, _
        Optional NoOverwrite As Boolean = False) As Boolean
    Dim lHandle As Long
    Dim lSuccess As Long
    Dim lBytesWritten As Long, lBytesToWrite As Long
    lBytesToWrite = Len(TheData)
    lHandle = CreateFile(Filename, GENERIC_WRITE Or GENERIC_READ, _
                         0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
    
    If lHandle <> INVALID_HANDLE_VALUE Then
       lSuccess = WriteFile(lHandle, ByVal TheData, _
                            lBytesToWrite, lBytesWritten, 0) <> 0
       If lSuccess <> 0 Then
          lSuccess = FlushFileBuffers(lHandle)
          lSuccess = CloseHandle(lHandle)
       End If
    End If
    ErrorHandler:
    WriteStringToFile = lSuccess <> 0
    End Function
    Code:
    Public Function CreateFileApi(Filename As String, _
        Optional NoOverwrite As Boolean = False) As Boolean
    
    Dim lSuccess As Long
    If NoOverwrite = True And Dir(Filename) <> "" Then Exit Function
    
    lHandle = CreateFile(StrPtr(Filename), GENERIC_WRITE Or FILE_APPEND_DATA, _
                         0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
    
    End Function
    Code:
    Public Function WriteBytesToFile(Filename As String, TheData() As Byte, _
    lcurByte As Long, Optional NoOverwrite As Boolean = False, Optional lisFinish As Boolean = False) As Boolean
    
    Dim lSuccess As Long
    Dim lBytesWritten As Long, lBytesToWrite As Long
    
    If NoOverwrite = True And Dir(Filename) <> "" Then Exit Function
    lBytesToWrite = (UBound(TheData) - LBound(TheData) + 1)
    
    If lisFinish = True Then
          MsgBox "Finish"
          lSuccess = FlushFileBuffers(lHandle)
          lSuccess = CloseHandle(lHandle)
          Exit Function
    Else
        If lHandle <> INVALID_HANDLE_VALUE Then
            lSuccess = WriteFile(lHandle, lcurByte, _
                lBytesToWrite, lBytesWritten, 0) <> 0
        End If
    End If
    
    
    ErrorHandler:
    WriteBytesToFile = lSuccess <> 0
    End Function
    Çà ïî äîáðî îíàãëåäÿâàíå ïðèêà÷àì è ïðèìåð.
    Attached Files

  13. #13
    Registered User
    Join Date: Nov:2006
    Location: varna
    Posts: 10

    Unhappy

    Àêî íÿìàòå èäåÿ çà òîçè ìåòîä, ìîæå äà ñïîäåëèòå íÿêîé äðóã, êîéòî äà ðàáîòè ñ óíèêîä ïúò.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Copyright © 1999-2011 Õàðäóåð ÁÃ. Âúçìîæíî å ñúäúðæàíèåòî íà òàçè ñòðàíèöà äà å îáåêò íà àâòîðñêè ïðàâà.
iskamPC.com | mobility.BG | Bloody's Techblog | Êðèïòîâàëóòè è ìàéíèíã | 3D Vision Blog | Ìàãàçèí çà åëåêòðîííè öèãàðè