Strona: [  << <   1 2   > >>  ]  z  2     
Autor Temat: Jak zrobić program z wielojęzykowym interfejsem i się nie namęczyć...?
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002
Jak zrobić program z wielojęzykowym interfejsem i się nie namęczyć...?

Witam!
Zastanawiam się jak w prosty sposób zaimplementować w programi wielojęzykowy interfejs. Jeden program z takim iterfejsem już napisałem - Advanced Signaler - http://www.michmajsoftware.prv.pl . Użyłem tam jednak osobnego wczytywania tekstu do każdej kontrolki z pliku INI korzystając z nazw tekstowych. Nigdy więcej! Strasznie dużo roboty, a jak potem coś trzeba przrobić w programie, to już lepiej nie mówić...
W wielu aplikacjach widzę, że kolejne numery w pliku językowym są numerami. Próbowałem więc zamieniąc teksty kontroler w pętli, korzystając z tablicy kontrolek. Niestety mój program jest zbyt "poszatkowany" na różne formy, a tablica kontroler (chyba) może działać tylko dla jednej formy i dla tej samej rodziny kontrolerk (np. labeli). Tak więc szukam jakiegoś prostrzego sposobu...
Może ktoś ma jakiś pomysł?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 14:08
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
Piotr T




Typ: neutral
Postów: 176
Zarejestrowany: May 2004

Skorzystaj z plików RES


_____________________________________________
Visual Basic.NET - Mercedes dla programistów

13-11-2004 14:42
Pokaż profil Piotr T  Wyślij email do Piotr T   Odwiedź stronę Piotr T  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

O plikach res wiem tyle, że to pliki zasobów (skrót o resources), mają (chyba) rozszerzenie *.rc, można je edytować ResourceHackerem, Resoratorem i..... tyle. Nie znam ich architektury i nie bardzo wiem jak miałyby mi pomóc. Mógłbyś nakreślić temat szerzej?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 14:45
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

Bardzo dziwne-dostałem powiadomienie, że marcin_an odpowiedział na tego posta, a tu nic...


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 15:27
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Proponuję coś takiego:
Public Sub SetLanguage(sData As String)
    Dim sLines() As String
    Dim vLine As Variant
    Dim sLine() As String
    Dim sObjID() As String
    Dim frmS As Form
    Dim frmForm As Form
    Dim ctlS As Control
    Dim ctlControl As Control
   
    sLines = Split(sData, vbCrLf)
    For Each vLine In sLines
        If CStr(vLine) = "" Then GoTo lenumenext
        sLine = Split(CStr(vLine), " == " )
        If UBound(sLine) = 0 Then GoTo lenumenext
        If sLine(0) = "" Then GoTo lenumenext
        sObjID = Split(sLine(0), "." )
        If UBound(sObjID) = 0 Then GoTo lenumenext
        For Each frmS In Forms
            If frmS.Name = sObjID(0) Then
                Set frmForm = frmS
                Exit For
            End If
        Next
        If frmForm Is Nothing Then GoTo lenumenext
        If UBound(sObjID) = 2 Then
            For Each ctlS In frmForm.Controls
                If ctlS.Name = sObjID(1) Then
                    Set ctlControl = ctlS
                    Exit For
                End If
            Next
            If ctlControl Is Nothing Then GoTo lenumenext
            CallByName ctlControl, sObjID(2), VbLet, sLine(1)
        Else
            CallByName frmForm, sObjID(1), VbLet, sLine(1)
        End If
lenumenext:
    Next
End Sub


W parametrze sData podajesz dane.
A dane są zapisywane w takim formacie:
W jednej linii znajduje się tekst dla jednego elementu. Linie są oddzielone parami znaków CrLf (vbCrLf).
Składnia linii:
forma.kontrolka.własciwość == tekst
lub jeśli chcesz przypisać właściwość formie:
forma.właściwość == tekst
I cztery wazne rzeczy:
1) Dane nie mogą zawierać dodatkowych spacji itp.
2) Nie można zastąpić " == " ciagiem "== ", "==" czy "==  ".. tam musi być " == ".
3) Wszystko, co będzie po drugim wystapieniu " == " w linii zostanie ucięte (można traktować jako komentarze).
4) Procedura jest czuła na wielkośc liter. Wielkość liter musi się zgadzać z tymi w nazwie obiektu, inaczej VB wypluje błąd...

Przykładowe dane dla formatki o nazwie Form1 zawierającej dwa Labele [Label1, Label2] i jeden Textbox [Text1]:

Form1.Caption == To jest fromatka
Form1.Label1.Caption == To jest pierwszy label
Form1.Label2.Caption == To jest drugi label
Form1.Label2.FontName == Courier new
Form1.Text1.Text == A to jest textbox

Jak widac, tą procedurką można nadawać wartość dowolnej zmiennej String. I jak narazie tylko zmiennym String. Może w przyszłości ją rozbuduję.

[Post edytowany dnia 13-11-2004 15:32 przez marcin_an]


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

13-11-2004 15:29
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Sorry za to powiadomienie... już jest wszystko ok .

I uwaga nr. 5:
Wskazane właściwości i obiekty MUSZĄ istnieć. Inaczej procedura także będize miała błędy. Poprostu, żeby nie komplikowac zapisu nie dodałem niczego do obsługi błędów .

[Post edytowany dnia 13-11-2004 15:33 przez marcin_an]


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

13-11-2004 15:29
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

Nic się nie stało i dzięki za procedurę. Oczywiście dane mogą być zapisane w *.INI i odczytywane sposobem "linia po linii"?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 15:32
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

I tak i nie .
Tzn. w kaslycznym INI jest inna składnia, więc nie mogą być. W INI składnia jest taka:

[sekcja]
zmienna1 = dane
zmienna2 =  dane    ;komentarz
zmienna3=  dane ;komentarz
;komentarz
[sekcja2];komentarz
zmienn41            = daneblablabla ;;; 31rjx9 ==

Natomiast tutaj składnia jest taka:

form1.obiekt1.caption == jakiś tekst
form1.obiekt1.caption == jakiś tekst 2 == komentarz balbalbla
form2.obiekt3.text == jakiś tekst..

Zatem różnica jest znaczna.
Natomiast przechowywać można w jakim się chce pliku... to nie ma znaczenia, oby składnia została zachowana.
Co do wczytywania linijka po linijce - jest to możliwe, ale trochę bez sensu zważywszy na to, ze procedura jest przygotowana pod dane wielolinijkowe i tak będzie działała bardziej wydajnie .


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

13-11-2004 15:37
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

To może mi podrzucisz sposób odczytywania takich danych z pliku TXT? Ja korzystam z takiego modułu do odczytu plików INI, ale widzę, że chyba nie bardzo da się ją zastosować...

Option Explicit
' Ścieżka do pliku INI
Public PlikINI As String

'Deklaracja funkcji do obsługi pliku INI
Private Declare Function GetPrivateProFileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal Appname As String, ByVal KeyName As Any, ByVal NewString As Any, ByVal Filename As String) As Integer

Public Sub SkasujDzial(ByVal Dzial As String)
  WritePrivateProfileString Dzial, 0&, "", PlikINI
End Sub

Public Sub ZapiszDoINI(Dzial As String, Klucz As String, Wartosc As String)
  WritePrivateProfileString Dzial, Klucz, Wartosc, PlikINI
End Sub

Public Function CzytajZINI(Dzial As String, Klucz As String) As String
Dim retval As Variant
Dim t As String * 500

  retval = GetPrivateProFileString(Dzial, Klucz, "", t, Len(t), PlikINI)

  If retval > 0 Then
      CzytajZINI = Left$(t, retval)
  End If
 
End Function



I na koniec: to będzie dla kogoś kto będzie tłumaczył ręcznie bardzo kłopotliwe pamiętać o tych spacjach przed i po "==". Nie dałoby się jakoś tego uniknąć?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 15:51
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

Marcin, serdeczne dzięki za ten kod! Tak chciałem zrobić na początku (chodzi mi o idee), ale mówiono mi, że to niemożliwe... . To przyspiesza lokalizację 100-krotnie! Powiedz mi tylko, czy jak zmienię te znaki " == " na "==", to nic się nie stanie? Zmieniłem i działało, ale nie sprawdzałem dokładnie, a podejrzewam, że jest jakiś powód dla którego dałeś " == " . Prawda?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 16:17
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Mm.. jeśli sie da samoe "==" to teoretycznie nie powinno działać, dlatego lepiej dać " == ". Natomiast tam gdzieś w kodzie jest taka linijka:
sLine = Split(CStr(vLine), " == " ).
Tam jest taki string: " == ".
Jeśli zamienisz ten ciąg znaków na "==", to w danych będziesz mógł pisać "==", z tym, że wtedy musisz pamiętać, żeby nie wpisać np. " == ", bo nie zadziała prawidłowo . W kodzie zamiast " == " możesz używać czegokolwiek i wtedy TO SAMO możesz uzyć w danych. Ja użyłem " == ", bo trudno o powtórzenie tego ciągu w przypisywanym tekście .

[Post edytowany dnia 13-11-2004 17:04 przez marcin_an]


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

13-11-2004 17:03
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

Twój kod nie działa dla formy, która nie jest załadowana do pamięci! Wyczynia wtedy różne .... na formie, którą ostatnio zmieniała... Co Ty na to?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 19:36
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Cytuję uwagę nr. 5:
"I uwaga nr. 5:
Wskazane właściwości i obiekty MUSZĄ istnieć"


Spróbuj gdzieś tam dodać sprawdzenie, czy dany obiekt jest załadowany do pamięci i tyle .

[Post edytowany dnia 13-11-2004 20:05 przez marcin_an]


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

13-11-2004 20:05
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

Przecież istnieją, tylko nie są załadowane...

1.) Nie da się tego przerobić?
2.) Nie wiem jak napisać procedurkę do sprawdzania czy coś jest załadowane do pamięci...
3.) Czy jak poleceniem Load załaduję najpierwsz wszytskie formatki do pamięci, potem odpalę Twoją procedurę, a potem jest wyładuję z pamięci, to nie będzie OK?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 20:12
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

0) Jeśli nie są załadowane to nie istnieją
1) ... patrz niżej
3) Owszem, procedura zadziała, ale jeśli je potem wyładujesz z pamięci, to wszystkie zmiany stracisz .
2) A ja jestem zaskoczony, bo spojrzałem i widzę, że tam jest kod sprawdzania, czy wskazany obiekt istnieje... :/ Nie wiem, co jest nie tak. Formy, które nie są załadowane nie powinny się znaleźć w kolekcji Forms, czyli procedura nie powinna ich widzieć... :/.
Może poprostu spróbuj poprostu ich nie wyładowywać i tyle?


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

13-11-2004 20:57
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

To wszystko dość znacznie komplikuje sprawę, bo chciałem zmienić wszystkie teksty po kliknięciu jednego przycisku na wszytskich formatkach...

Formy nie mogą być w pamięci cały czas, bo program czuwa w tle , a do tego MNIE skomplikowałoby to życie, bo te formy mają kupę kodu w Form_Load()...

Tak więc pozostaje mi zmiana tekstu przy wywołaniu dnaje formy. To nie problem, bo wszystko mam w publicznej funkcji, ale dzieją się takie dziwne rzeczy, że mimo tego rzekomego zabezpieczenia jak mam załóżmy tak:

frmmain.Caption==tytuł
frmmain.lblopis.Caption==opis
frmmain.frmoption.Caption==opcja
frmadd.Caption==Coś

I frmmain jest w pamięci, a frmadd nie, to frmmain.frmoption.Caption dostaje tytuł "Coś".

Dałoby się temu jakoś zaradzić?


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


13-11-2004 21:33
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Mam pewien pomysł. Pomiędzy tymi dwoma liniami:

    For Each vLine In sLines
        If CStr(vLine) = "" Then GoTo lenumenext

dodaj linię
Set FrmForm = Nothing
I tutaj przyznaję, że zrobiłem błąd w kodzie, bo powinienem dodać tą linijkę . Z powodu jej braku, gdy nie znalazł wskazanej formatki (bo nie było jej = nie była załadowana), używał tego, co miał w zmiennej FrmForm... w naszym przypadku - poprzedniczki. Teraz będzie miał za każdym razem Nothing i tym samym nie zrobić nic dla nieistniejącej .


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

14-11-2004 03:36
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Powiem więcej - żeby kod był bardziej efektywny, dodaj ją po tych dwuch liniach.


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

14-11-2004 03:37
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Viper87



Typ: neutral
Postów: 490
Zarejestrowany: Oct 2002

Problem zniknął częściowo-jak teraz wpiszę nazwę komponentu, którego nie ma na załadowanej formie, to dziej się to co poprzednio, czyli:

frmmain.przycisk1.Caption==Napis1
frmmain.prycisk2.Caption==Napis2

Forma frmmain jest załadowana, w drugiej lini zrobiłem jednak celowo literówkę, żeby Ci pokazać, że przycisk1 otrzyma tytuł "Napis2".

Co do poprzedniego problemu, to już nie występuję-kod rozpoznaje, że forma nie jest załadowana .


_____________________________________________
Viper

"Savoir c`est prevoir, prevoir c`est prevenir". 
(Wiedzieć to przewidzieć, przewidzieć to zapobiegać) 


14-11-2004 17:47
Pokaż profil Viper87  Wyślij email do Viper87   Odwiedź stronę Viper87  
marcin_an
Forumowicz




Typ: neutral
Postów: 1265
Zarejestrowany: Mar 2004

Jak robić błedy, to ten sam błąd seryjnie. Tak jak Microsoft. Oczywiście błąd polega na tym samym i tym razem trzeba wyczyścić tą samą metodą, w tym samym miejscu zmienną ctlControl . Dodaj kod:
Set ctlControl = Nothing zaraz pod tym, który dodałeś wcześniej.
Nie ma to jak beta-testrzy .

[Post edytowany dnia 14-11-2004 18:29 przez marcin_an]


_____________________________________________
Jedzonko dla Google'a:
Forum na temat Visual Basic, C, C++, Pascal, Programowanie, API, PHP, VBA, VB.NET, QBasic, VBScript, Komputery
Moja strona o wszystkim

14-11-2004 18:28
Pokaż profil marcin_an  Wyślij email do marcin_an   Odwiedź stronę marcin_an  
Wszystkich odpowiedzi: 23 :: Maxymalnie na stronę: 20
Strona: [  << <   1 2   > >>  ]  z  2