Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB.NET ja grafiikka (C)

Sivun loppuun

JoreSoft [25.12.2007 11:50:31]

#

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.

neau33 [25.12.2007 15:32:25]

#

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-

JoreSoft [25.12.2007 16:29:31]

#

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?

neau33 [25.12.2007 17:29:52]

#

Heippa taas JoreSoft!

Mikä VS.NET/VB.NET & Framework versio sulla on käytössä?

JoreSoft [25.12.2007 23:19:46]

#

Visual studio 2005 pro ja Framework 3.5

neau33 [26.12.2007 04:42:35]

#

tsekkaa tuolta -> http://mureakuha.com/keskustelut/11?15319p#box

JoreSoft [29.12.2007 16:27:48]

#

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??

Metabolix [29.12.2007 16:46:19]

#

Kannattaisi stringiä 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?

JoreSoft [29.12.2007 17:10:44]

#

Annatko hieman tarkemman esimerkin, että miten tuota merkkijono sotkua vois purkaa :D
on meinaan nuita &, * yms viittauksia vaikka muille jakaa...

Metabolix [29.12.2007 17:14:28]

#

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.

JoreSoft [29.12.2007 17:30:44]

#

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;
  }
}

Metabolix [29.12.2007 17:39:47]

#

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ä.

JoreSoft [29.12.2007 18:26:41]

#

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 =)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta