QB:ssä on kiinnostavia ominaisuuksia, kuten tuo Antin koodivinkki muistiin tallennetusta luvusta. VB:ssä ei ole PEEK- eikä vastaavaa POKE-käskyä. Jos VB:llä käynnistää QB-ohjelman voiko muuttujien sisältöä siirtää toiseen ohjelmaan jotenkin suoraan parametreina vai onnistuuko PEEK ja POKE VB:ssä jollain API-funktiolla?
Aikamoista kikkailua vaatii. Tiedän erään joka jonkinlaisen tällaisen tekikin (muistaakseni) mutta hän näyttää olevan off linessa. Voin kysäistä kun näen.
Etkö voisi käyttää tiedostossa siirtämistä? Kävisi varmaan hieman helpommalla.
Noin teen jos ei parempaa konstia löydy.
SendMessage API:lla onnistuu. En tähän hätään löytänyt googlella esimerkkiä asiasta, mutta mulla on tuosta oma versioni kotona jossain tallessa, jossa kaksi erillistä VB:llä tehtyä ohjelmaa juttelee keskenään. Kai tuo on mahdollista muokata myös QB:llä toimivaksi. Voin laittaa koodin jonnekkin kopioitavaksi, kun pääsen illalla kotiin.
Jospa BadSource löytäisit oman versiosi SedMessage API:sta olisin hyvin kiitollinen.
Uskaltaisin kyllä väittää, ettei QB:llä toimi WinAPI.
Kiinnostaisi tuo tiedon siirto vaikka vain VB-ohjelmien kesken.
Nyt on pää niistetty tyhjäksi, joten alkaa muistikin palata pätkittäin.
Tuossa linkki kaivattuun esimerkkiin. Googlella asiasta löytää esimerkkejä mm. hakusanoilla vb VB_WindowProc, joiden pohjalta tuon omani olen joskus askarrellutpaskarrellut.
Kiitokset vastauksista ja esimerkistä.
Heippa!
Hieman mietityttää toi VB - QB jutska, koska toi API SendMessage tai vaikka DDE-linkityksen onnistuminen perustuu siihen että vastaanottavan ohjelman johokin kontrolliin saadaan yhteys.
Esim. AppActivate "Title": SendKeys "{TAB}" jne...
Mutta mistä löytyy QB:ssä se kontrolli johon luoda yteys/josta napata kahva?
Sen sijaan WriteMemory()/ReadMemory() -funktioilla voisi ehkä kikkailla VB:ssä ja QB:ssä vaikkapa Open "COM..., Call Absolute(), OUT(), & INP()-funktioilla
Kiitos Nea mutta taisin iskeä kirveeni kiveen. Kunnioitettavan näköisiä esimerkkejä mutta menee turhan mutkikkaaksi todellakin. Tyydyn siirtoon tietoston kautta.
lainaus:
Mutta mistä löytyy QB:ssä se kontrolli johon luoda yhteys/josta napata kahva?
Tunnen QB:tä varsin huonosti, mutta esimerkissäni tuota varten luodaan erilinen formi, jonka kahva toimii SendMessagen kahvana. CreateWindowEx palauttaa suoraan luomansa ikkunan kahvan onnistuneen kutsun yhteydessä. HInstancea tarvitaan kohteena, johon CreateWindowEx sitoo luomansa ikkunan. HInstancen taas saa selville GetModuleHandle API:lla, jos QB ei sitä suoraan tunne/palauta.
'VB-esimerkki GetModuleHandlen käytöstä Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (Optional ByVal lpModuleName As String) As Long Dim hInstance As Long 'jos moduulia ei nimetä, niin GetModuleHandle palauttaa kutsujan hInstancen hInstance = GetModuleHandle 'VB:llä App.hInstance
FindWindow API antaa halutun ikkunan kahvan, jos tämän otsikko tiedetään, jolloin toinen ohjelma osaa etsiä kenelle viestinsä lähettää.
Toisin sanoen, jos QB:ssä pystyy kerran tekemään API-kutsuja, niin kahva ei ole mikään ongelma.
Hm. Ei luultavimmin pysty. Kirjastot pitäisi linkata myös .qlb / .bi -tiedostoiksi. QB on DOSille. Sitten voi tietenkin antaa parametrinä komennon ja arvot. Veikkaanpa, että joudut joko antamaan parametreinä asiaa tai sitten tallentamaan tiedostoon.
Heippa taas!
Jos nyt välttämättä haluaa välttää tiedoston käyttöä QB <-> VB väliseen tiedonsiirtoon niin siirron voisi toteuttaa esim. sarjaportin kautta.
Ekaks olis hyvä rakennella loopback plugi
'QB esimerkki:
DECLAREC SUB KirjoitaPorttiin(): DECLAREC SUB LuePortista()
DIM SHARED tavut AS INTEGER, COM$
tavut = 2 * 8
Paluu:
CLS: LOCATE 1, 1: INPUT "Valitse COM portti (1 tai 2): "; portti%
SELECT CASE portti%
CASE 1
COM$ = "COM1"
CASE 2
COM$ = "COM2"
CASE ELSE
CLS: LOCATE 1, 1: PRINT "Virheellinen arvo! Jatkatko K/E?"
DO
SELECT CASE UCASE$(INKEY$)
CASE "K": GOTO Paluu
CASE "E": CLS: SYSTEM
END SELECT
LOOP
END SELECT
CLS: Ohje
DO
SELECT CASE UCASE$(INKEY$)
Case "A": GOTO Paluu
CASE "L": LuePortista
CASE "K": KirjoitaPorttiin
END SELECT
LOOP UNTIL INP(&H60) = 1
CLS: SYSTEM
SUB KirjoitaPorttiin()
CLS
LOCATE 1, 1: PRINT "LUKUARVON SYÖTTÖ: Paina L"
LOCATE 2, 1: PRINT "MERKKIJONON SYÖTTÖ : Paina M"
DO
SELECT CASE UCASE(INKEY$)
DIM dataStr AS STRING
CASE "L": INPUT "Lukuarvo: "; xdata&: dataStr = LTRIM$(STR$(xdata&))
EXIT DO
CASE "M": INPUT$ "Merkkijono: "; dataStr
IF dataStr <> "" THEN dataStr = dataStr + SPACE$(tavut - LEN(dataStr))
EXIT DO
CASE ELSE: BEEP
END SELECT
LOOP
IF LEN(dataStr) > tavut THEN dataStr = LEFT$(dataStr, tavut)
OPEN COM$ + ":9600,N,8,1,RS,DS" FOR RANDOM ACCESS WRITE AS #1 LEN = tavut
PUT #1, 1, dataStr: CLOSE #1 CLS: ohje
END SUB
SUB LuePortista()
DIM dataStr AS STRING
CLS
OPEN COM$ + ":9600,N,8,1,RS,DS" FOR RANDOM ACCESS READ AS #1 LEN = tavut
GET #1, 1, dataStr: CLOSE #1 :LOCATE 3, 1
PRINT COM$ +" DATA: " + dataStr
Ohje
END SUB
SUB ohje()
LOCATE 1, 1
PRINT "Alkuun=A kirjoita porttiin=K Lue portista=L Sulje=Esc"
END SUB
' HUOM! älä kopioi tätä koodia suoraan QBasic'iinTässä vielä mielenkiintoinen linnki
VB:ssä vois sit käytellä MSComm-kontrollia, jonka toiminnoista löytyy tietoa raahaamalla kontrolli formille, aktivoimalla & painamalla F1-näppäintä.
Kiitos Nea. Tietoa löytyy niin että nuppia pakottaa.
Heippa taas!
Tiedostotasolla tehty siirto voisi olla vaikkapa tälläinen...
'QB ohjelma (C:\HelloVB.Bas) DECLARE SUB WriteData(): DECLARE SUB ReadData(): DECLARE SUB HelpText() COMMON SHARED stringi$, lyhyt%, lonkku&, sinkku!, tupla#, visiitti% DIM SHARED QbCrLf AS STRING QbCrLf = CHR$(10) + CHR$(13) HelpText IF visiitti = 1 THEN visiitti = 0 LOCATE 2,1: PRINT "stringi$ = " + stringi$ LOCATE 3,1: PRINT "lyhyt% = " + TRIM$(STR$(lyhyt%)) LOCATE 4,1: PRINT "lonkku& = " + TRIM$(STR$(lonkku&)) LOCATE 5,1: PRINT "sinkku = " + TRIM$(STR$(sinkku!)) LOCATE 6,1: PRINT "tupla# = " + TRIM$(STR$(tupla#)) END IF DO SELECT CASE UCASE$(INKEY$) CASE "R": SendData CASE "W": ReadData CASE ELSE: BEEP END SELECT LOOP UNTIL INP(&H60) = 1 'Esc CLS: SYSTEM SUB ReadData) ON ERROR GOTO ErrorHandler CHAIN "C:\HelloQB.Bas" EXIT SUB ErrorHandler: ERR = 0 Msg$ = "File doesn't exists!" LOCATE 13, 40 - (LEN(Msg$) / 2): PRINT Msg$ RESUME NEXT END SUB SUB WriteData() Scripti$ = "Sub Scripti()" + QbCrLf Scripti$ = Scripti$ + "stringi$ = " + Chr$(34) + "Hello VB!" + CHR$(34) + QbCrLf Scripti$ = Scripti$ + "lyhyt% = 1000 * 1000" + QbCrLf Scripti$ = Scripti$ + "lonkku& = 1000000 * 1000000" + QbCrLf Scripti$ = Scripti$ + "sinkku! = 1000.0001 * 1000.0001" + QbCrLf Scripti$ = Scripti$ + "tupla# = 1000000.0000001 * 1000000.0000001" + QbCrLf Scripti$ = Scripti$ + "End Sub" OPEN "C:\HelloVB.txt" For OUTPUT AS #1: PRINT #1, Scripti$: CLOSE #1 END SUB SUB HelpText() Header$ = "R=Read data W=Write data Esc=Quit" CLS: LOCATE 1, 40 - (LEN(Header$) / 2): PRINT Header$ END SUB
'VB Ohjelma (HelloQB.vbp - HelloQB.frm)
'Lisää referenssit: Microsoft Script Control 1.0
'sekä Microsoft Scripting Runtime Library
Public stringi$, lyhyt%, lonkku&, sinkku!, tupla#
Private Sub cmdReadData()
Dim sc As MSScriptControl.ScriptControl
Dim fso As FileSystemObject
Set fso = New FileSystemObject
If fso.FileExists("C:\HelloVB.txt") Then
Dim ScriptStr As String
Set sc = New MSScriptControl.ScriptControl
Open "C:\HelloVB.txt" For Input As #1
ScriptStr = Input$(LOF(1), 1): Close #1
With sc
.Language = "VBScript"
.AddObject "Form1", Me, True
.AllowUI = True
.AddCode ScriptStr
.Run "Scripti"
End With
Set sc = Nothing
Else
MsgBox "File doesn't exists", VbExclamation, Me.Caption
End if
Set fso = Nothing
End Sub
Private Sub cmdShowData_Click()
Static i As Integer
Select Case i
Case 0
Text1.Text = stringi$: i = i + 1: Exit Sub
Case 1
Text1.Text = lyhyt%: i = i + 1: Exit Sub
Case 2
Text1.Text = lonkku&: i = i + 1: Exit Sub
Case 3
Text1.Text = sinkku!: i = i + 1: Exit Sub
Case 4
Text1.Text = tupla#: i = 0: Exit Sub
End Select
End Sub
Private Sub cmdWrite()
Open "C:\HelloQB.Bas" For Output As #1
Print #1, "COMMON SHARED stringi$, lyhyt%, lonkku&, sinkku!, tupla#, visiitti%" & vbCrLf _
& "visiitti% = 1" & vbCrLf _
& "stringi$ = Chr(34) & "Hello QB" & Chr(34) & vbCrLf" _
& "lyhyt% = 2000 / (1 / 2000)" & vbCrLf _
& "lonkku& = 2000000 / (1 / 2000000)" & vbCrLf _
& "sinkku! = 2000.0001 / (1 / 2000.0002)" & vbCrLf _
& "tupla# = 2000000.000002 / (1 /2000000.0000002)" & vbCrLf _
& "CHAIN " & Chr(34) & "C:\HelloVB.Bas" & Chr(34)
End SubKiitoksia paljon. Tässä riittää sulateltavaa.
Aihe on jo aika vanha, joten et voi enää vastata siihen.