Olen vihdoinkin siirtymässä .net ohjelmoijaksi.
Kokeilin kääntää vanhaa VB6.0 ohjelmaa sille, ja tuli ongelmia.
Vanha ohjelma käyttää luokissa BitBlt, TextOut,GetPixel,SetPixel, TransparetBlt yms. apeja, joilla pääformin PictureBox:iin viitattiin.
Voiko Visual Basic .net:ssä viitata formilla olevaan picturebox:iin muualla kuin
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim g As Graphics = e.Graphics
tyyliin?
Voiko siis luoda globaalia "g As Graphics" muuttujaa, johon voisi viitata missä luokassa/moduulissa vaan?
Ja Toinen kysymys on toi tekstin piito kuvaan. (TextOut tai Print)
ja kolmas Rajatun alueen kopiointi kuvasta toiseen =) (Bitblt)
ja vielä tärkein kysymys. Saavutanko nopeusetua muuttamalla koodin VB.net ympäristöön? Ohjelma tunnistaa mustavalkoisesta kuvasta merkkivalikoimaan sopivia kohtia, ja tekee näin teksti-grafiikkaa.
Tunnistaminen VB6-ohjelmalla on hidasta, vaikka vertailtavia merkkejä on vain 5-10 kpl.
Heippa JoreSoft!
tässä hieman vinkkiä...
'tee tässäkin toi pisteen perään iskeminen... 'Imports System.Drawing. '...tutki ja vertaa mitä kivaa laatikoista sit löytyy... Public Class Form1 Inherits System.Windows.Forms.Form 'mikäli päädyt käyttämään API-kamaa niin määrittele vakiot tyyliin... 'Public/Private Const JOKU_VAKIO AS tyyppi = jotain 'ja API-funktiot tyyliin... 'Public/Private Declare Auto Function jne... '... Public Shared g As Graphics 'tämä funkkaa mistä vaan... 'toki voit iskeä projektiin moduulin, 'jossa esittelet jutskan aivan samaan 'tyyliin...tai sit teet luokan ja 'kapseloit koko paskan, mutta... 'miksi nähdä vaiva... Protected Overrides Sub OnPaint(ByVal _ e As System.Windows.Forms.PaintEventArgs) g = e.Graphics 'nyt kun olet tässä vaiheessa niin iske ' . (piste ton Graphics-sanan perään) *** 'ja tutki mitä kaikkea kivaa siihen 'dropdown-laatikkoon ilmestyy... 'voit sit alkaa miettiin kannattaako 'noita API-jutskia tuoda projektiin... 'mikäli haluat silti käyttää API-funktioita... 'niin mikään ei estä... End Sub '...
-Nea-
Kiitos Nea =)
Ei ole tarkoitus liittää niitä apeja, vaan etsiä vastaavia käskyjä vb.net
Toi GDI+ varmaan on jonkinlainen vastaus?
Kun huomasin, että esim Getpixel ja Setpixel ei saa Graphic:lla tehtyä.
kun taas
bmp = New Bitmap(W, H) tukee noita... mikä siis olisi sellainen, että tukee tekstin tulostusa, getpixel, setpixel, ja kuvaosan kopiointia.. yms
Laskee kuvasta Mark()-merkkijonotaulukon mustien pikseleiden määrän.
Public Function CountCharBlack(X%, Y%, Le%) As Integer Dim X1%, Y1%, Col1&, Col2&, I%, Ch$ With PL .M.ForeColor = vbBlack .M.BackColor = vbWhite For I = 1 To Le F(I) = 0 'Nollataan laskuri .M.Cls Ch = Mark(I) TextOut .M.HDC, 0, 0, Ch, 1 'Tulostetaan 1 merkki vertailu pictureBoxiin .M.Refresh DoEvents Y1 = 0 X1 = 0 'Vertaillaan jokaista pixeliä Do Do Col1 = GetPixel(pW.HDC, X + X1, Y + Y1) Col2 = GetPixel(.M.HDC, X1, Y1) If Col1 = Col2 And Col1 = vbBlack Then F(I) = F(I) + 1 'Lisätään Y1 = Y1 + 1 Loop Until Y1 > SF(I).sY 'Kirjaimen etukäteen laskettu korkeus Y1 = 0 X1 = X1 + 1 Loop Until X1 > SF(I).sX 'Kirjaimen etukäteen laskettu leveys Next I CountCharBlack = SearchKing(X, Y, Le) 'Tutkitaan hallitseva merkki. End With End Function
ja samasta yritelmä .NET
Public Function CountCharBlack(ByRef X As Short, ByRef Y As Short, ByRef Le As Short) As Short Dim Y1, X1, I As Short Dim Col1, Col2 As Integer Dim Ch As String Dim M As PictureBox Dim M1 As New Bitmap(30, 30) Dim Br As SolidBrush Dim Musta = New Pen(Color.Black) M.Size = New Size(30, 30) M.ForeColor = Color.Black M.BackColor = Color.White For I = 1 To Le F(I) = 0 Ch = Merkki(I) 'TextOut(.M.HDC, 0, 0, Ch, 1) M.CreateGraphics.DrawString(Ch, PL.DefaultFont, Br, 0, 0) '1 merkki M.Refresh() M1 = M.Image ' Kopioidaan se?? Y1 = 0 X1 = 0 'vertaillaan Do Do Col1 = System.Drawing.ColorTranslator.ToOle(B.GetPixel(X + X1, Y + Y1)) Col2 = System.Drawing.ColorTranslator.ToOle(M1.GetPixel(X1, Y1)) If Col1 = Col2 And _ Col1 = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black) Then F(I) = F(I) + 1 End If Y1 = Y1 + 1 Loop Until Y1 > SF(I).sY Y1 = 0 X1 = X1 + 1 Loop Until X1 > SF(I).sX Next I Return SearchKing(X, Y, Le) End Function
Värien vertaaminen IF-lauseessa on kans ongelma, joten muutan ne Integer numeroksi ja vertaan vasta sitten :D onko muuta tapaa?
Heippa taas JoreSoft!
Mikä VS.NET/VB.NET & Framework versio sulla on käytössä?
Visual studio 2005 pro ja Framework 3.5
tsekkaa tuolta -> http://mureakuha.com/keskustelut/11?15319p#box
Jatkan tähän samaan aiheeseen vielä... =)
Joska tuossa mainitsemassani ohjelmassa on paljon nopeuskriittisiä aliohjelmia (VB on hidas), kokeilin tehdä DLL-kontrollin Visual C++:lla.
Tuli muutama ogelma:
muuttuja merkit saa tässä onnistuneesti merkkijonon.
FUNKTIOT_API int __stdcall SetMM(char *m) { merkit = m; // MessageBox(NULL,merkit ,"Sample Code", NULL); return 1; }
mutta kun samaa muuttujaa luetaan, jotain menee pieleen...
FUNKTIOT_API char __stdcall GetMM(int Index) { char apu; apu=merkit[Index]; return apu; }
muuttujien määrittely on ohjelman alussa:
char *merkit={'\0'};
kokeilin myös muotoa:
string merkit;
mikä menee vikaan, kun GetMM, palauttaa hieman mitä sattuu??
Kannattaisi string
iä käyttää mieluummin, niin sattuisi vähemmän virheitä ja olisi dynaamisempi systeemi. Et ilmeisesti osaa char*
-tyyppistä muuttujaa käyttää oikein, sijoitustahan ei kuulu tehdä noin vaan kopioimalla sisältö, tuossa muuttuu vain osoitin ja hajoaa koko systeemi. Parametri toki saa olla char*
(mieluummin vielä const char*
), sen voi huoletta "sijoittaa" string
-olioon tuolla tavalla.
Toimivatko funktiot yleensäkään? Toimiiko esimerkiksi jonkin vakiokirjaimen palauttaminen oikein?
Annatko hieman tarkemman esimerkin, että miten tuota merkkijono sotkua vois purkaa :D
on meinaan nuita &, * yms viittauksia vaikka muille jakaa...
Tarkemmin mitä kohtaa et vielä ymmärrä? VB:n puolesta en osaa sanoa mitään, mutta C++-koodi näyttäisi jokseenkin tältä:
#include <string> std::string s; int SetMM(const char *t) { s = t; return 1; } char GetMM(unsigned int i) { if (i < s.length()) [ return s[i]; } else { return 0; } }
Ihan ensiksi voisit kuitenkin tarkistaa, että GetMM:n paluuarvo tulee perille. Laita se vaikka palauttamaan aina 'X' ja tarkista, että toimii.
Out of memorya alkoi nyt herjaan, kuin index suurempi kuin 0.
Private Declare Function SetMM Lib "Funktiot.dll" (ByVal Merkkijono As String) As Long Private Declare Function GetMM Lib "Funktiot.dll" (ByVal ind As Long) As String 'Test Private Sub Form_Load() Dim A$, I%, M$ MM = " liÎÏ!IÌÍ¡*°{}\/[]-¹²³‘’'´`¨·.¸,;:" Label1.Caption = MM Ret = SetMM(MM) Do M = GetMM(I) I = I + 1 If M <> Chr$(0) Then A = A & M Else Exit Do End If Loop MsgBox A End Sub
DLL ohjelman muutin näin.
FUNKTIOT_API int __stdcall SetMM(const char *t) { merkit = t; MessageBox(NULL,t ,"Sample Code", NULL); // ilmoittaa koko merkkijonon tallettuneen return 1; } FUNKTIOT_API char __stdcall GetMM(unsigned int ind) { if (ind < merkit.length()) { return merkit[ind]; } else { return 0; } }
Ongelma taitaa olla siinä, että GetMM ei palauta Stringiä vaan yhden tavun. Toimisiko muuttaa funktion tyypiksi As Byte
ja hakea merkki rakenteella Chr(GetMM(I))
?
Toinen vaihtoehto on kai muuttaa GetMM näin:
const char *GetMM(unsigned int i) { static std::string merkki; if (ind < merkit.length()) { merkki = merkit[ind]; } else { merkki = ""; } return merkki.c_str(); }
Luulisin, että ensimmäinen tapa on nopeampi, mutta eihän tuosta VB:stä koskaan tiedä.
Kiitos neucoista, sain toimiin sen =)
FUNKTIOT_API short __stdcall GetMM(unsigned int ind) { short merkki; if (ind < merkit.length()) { merkki = merkit[ind]; } else { merkki = 0; } return merkki; }
Hyvää vuotta 2008 !!!
meta ja muutkin =)
Aihe on jo aika vanha, joten et voi enää vastata siihen.