GetDC(Form1->Handle) von WIN7 zu WIN XP nicht = ?



  • Hallo,

    benutze eine Funktion mit Canvas GetDC(Form1-Handle) in zusammenarbeit mit TRect(x.x.x.x)...

    Wenn ich das Programm auf WIN 7 ausführe und dort die DC Koordinaten speichere, werden diese auch korrekt wieder gegeben, mit den passeneden Fensterinhalt.

    Kopiere ich das Programm mit den erstellten Koordinaten auf eine WIN XP Maschine, wird die GetDC Funktion mit den gleichen Koordinaten gefüttert, doch der Fenster inhalt ist versetzt.

    Es sieht so aus als ob er eine Stelle von Links hinzufügt, warum?

    Wie kann ich sicher stellen, daß ich Versions übergreifen die gleichen DC Bedingungen habe?

    Nachträglich der Code, ist ein Timer in dem ich mit einem Shape die zu Speichernde Region auswähle.
    Die lese Funktion sieht gleich aus, da wird aus der koordinaten Datei x.y ausgelesen.
    Würd mich mal interessieren ob das an der Positionierung des TRect liegt oder an GetDC Unterschieden unter den Betriebsystemen.

    TCanvas* Canvas = new TCanvas();
    Canvas->Handle = GetDC(Form1->Handle);
    
       Image1->Picture->Bitmap->Width = 16;
       Image1->Picture->Bitmap->Height= 16;
    
       TRect Ziel = Image1->ClientRect;
    
       TRect Quelle = Rect( Shape1->Left, Shape1->Top, Shape1->Left +16, Shape1->Top +16 );
       Image1->Picture->Bitmap->Canvas->CopyRect(Ziel, Canvas, Quelle);
       Image1->Picture->Bitmap->PixelFormat  =	pf24bit;
       //bild speichern
       ForceDirectories(Dir);
       Image1->Picture->Bitmap->SaveToFile(Dir+"\\"+koordinaten+".jpg");
       //koordinaten speichern
       ForceDirectories(Dir1);
       TStringList *list = new TStringList();
       list->Add(Shape1->Left );
       list->Add(Shape1->Top );
       list->SaveToFile(Dir1+"\\"+koordinaten+".txt");
       delete Canvas;
       delete list;
    

    THX für Rat, schönes WE



  • Code, bitte.



  • Von WIN 7 auf WIN 8 geht das auch nicht...

    Irgendwo muss doch da ein Unterschied zwischen den Versionen bei der Positionierung sein...

    Wer hat mit so was schon Erfahrung gemacht? oder weiss womit ich eine Einheitliche Positionierungs Basis in meinem Programm mitgeben kann?

    Welche alternativen zu TRect gibt es hierzu?
    Ist mein Handle mit GetDC(Form1->Handle) richtig? Alternativen?

    THX für Rat, schönen Sonntag noch



  • Der Auslese-Code wäre schon auch von Interesse, denn man kann bislang nur vermuten, was du letztendlich erreichen willst.
    Hast du schon geprüft, ob zumindest das gespeicherte Bild pixelgenau den von dir gewünschten/erhofften Inhalt hat?



  • Bild beim Start des Programms laden und Koordinaten...

    TStringList *listzitrone = new TStringList();
    Graphics::TBitmap *bmpzitrone2 = new Graphics::TBitmap();
    Graphics::TBitmap *bmpzitrone3 = new Graphics::TBitmap();
    bmpzitrone2->LoadFromFile(Dir+"\\zitrone.bmp") ;
    bmpzitrone3->LoadFromFile(Dir+"\\zitrone1.bmp") ;
    listzitrone->LoadFromFile(Dir1+"\\zitrone.txt");
    leftzitrone=listzitrone->Strings[0];
    topzitrone=listzitrone->Strings[1];
    TryStrToInt(leftszitrone, zitroneleft1);
    TryStrToInt(topzitrone, zitronetop1);
    

    Canvas Lesefunktion und Bildvergleich...

    Bitmap *bmp1 = new TBitmap();
    bmp1->SetSize(size1,size1);
    TCanvas* Canvas = new TCanvas();
    
    Canvas->Handle = GetDC(Form1->Handle);
     //SetGraphicsMode(Canvas->Handle, GM_ADVANCED); <-ein versuch
    Quelle = Rect(zitroneleft1 , zitronetop1  , zitroneleft1 + 16,zitronetop1+16 );
    
    bmp1->Canvas->CopyRect(bmp1->Canvas->ClipRect, Canvas, Quelle);
    bmp1->PixelFormat = pf24bit;
    
     if (vergleich(bmp1,bmpzitrone2)==true || vergleich1(bmp1,bmpzitrone3)==true)
    {
    //mach was
    }
    delete bmp1;
    delete Canvas;
    

    Warum heisst es eigentlich jetzt bei WIN 7 bei den DPI einstellung 9 punkte pro 96 DPI und bei WIN XP 10 punkte pro 96 DPI oder so ähnlich...?

    Ob das wohl damit zusammen hängt, hab da echt keine Idee mehr über die Tage wurde google zu 50% von mir belastet 🤡



  • Ich würde vermuten, daß du die Breite des Fensterrahmens nicht berücksichtigst ( BoundsRect != ClientRect ).

    Ansonsten bekomme ich bei deinem Code leider Bauchschmerzen:
    - potentielle Speicherlecks
    - Bitmap als ".jpg" gespeichert
    - GDI-Handle-Leak (in der Doku zu GetDC() steht "After painting with a common DC, the ReleaseDC function must be called to release the DC")

    • if (cond == true)
    • TryStrToInt() , ohne das Ergebnis zu überprüfen
      etc.


  • audacia schrieb:

    Ich würde vermuten, daß du die Breite des Fensterrahmens nicht berücksichtigst ( BoundsRect != ClientRect ).

    Danke für den Tip, komm noch nicht drauf wie ich das verwenden soll... 😕

    audacia schrieb:

    Ansonsten bekomme ich bei deinem Code leider Bauchschmerzen:
    - potentielle Speicherlecks
    - Bitmap als ".jpg" gespeichert

    Was hierbei das Problem wenn ich ein Bitmap Grafik Object im Grafischen JPG Format speichere? Ich weiss zwar das es eine JPG Include gibt, jedoch ist mir hierbei der Nachteil nicht klar.

    audacia schrieb:

    - GDI-Handle-Leak (in der Doku zu GetDC() steht "After painting with a common DC, the ReleaseDC function must be called to release the DC")

    Hab ich nicht mit aufgeführt, mach das Release so...

    ReleaseDC(Form1->Handle,NULL);
    ReleaseDC(NULL,Canvas->Handle);
    

    audacia schrieb:

    • if (cond == true)

    Raf ich nit was hier gemeint ist? Ich denke Du beziehst es hier auf den BMP Vergleich...

    audacia schrieb:

    • TryStrToInt() , ohne das Ergebnis zu überprüfen
      etc.

    OK werd ich mal schauen das ich das berücksichtige, da in den Koordinaten nur Ziffern stehen erwarte ich jedoch auch nur diese...

    Sagt mal hat den die Ausgabe auf zwei Monitoren damit vielleicht was zu tun?
    Einiges was ich so durchlese bezieht sich auch auf diesen Zusammenhang, daß wohl noch ein Externer Rahmen über die beiden Monitore gezogen wird und mit in den DC hineinfliesst.

    Wer da nicht so ganz schlau draus, auch in einer VM wir düber Probleme mit der DC Funktion gesproche und auch von CreateDC ist die Rede.

    Wie müsste ich den verfahren (mit welcher DC Funktion) um sicherzu stellen daß die koordinaten auch wirklich überall gleich sind?

    THX schon mal, wünsche was...



  • hawkdz schrieb:

    Was hierbei das Problem wenn ich ein Bitmap Grafik Object im Grafischen JPG Format speichere? Ich weiss zwar das es eine JPG Include gibt, jedoch ist mir hierbei der Nachteil nicht klar.

    Du speicherst ein Bitmap und gibst dem die Endung jpg. Deswegen ist es aber immer noch eine bmp-Datei. Nur weil du die Endung jpg anhängst wird daraus keine jpg-Grafik.

    hawkdz schrieb:

    if (cond == true)

    Das ist das Gleiche wie

    if(cond)
    

    .



  • Hat dein Windows 7 evtl eine 125%+ Skalierung und Windows XP 100% und deswegen sieht es unterschiedlich aus?

    Hast du schon mal probiert die Formeingenschaft Scaled auf false zu setzen um dieser Formskalierung zu ignorieren?



  • DPI Skalierung ist bei allen Systemen auf 96DPI (100%)

    Scaled Eigenschaft ist false

    Form BorderStyle auf bsNone gesetzt, test bringt wieder ein Versatz des TRects Left+1 und Top+1.

    Hab jetzt noch ein weiteres WIN 7 Ultimate ausprobiert, Koords und PIC kommt von WIN 7 Home Premium, das gleiche Problem das kann doch nit sein... 😡

    Dazu noch mal als Errinerung, Thema zwei Bildschirme und VMWare Maschine...
    Die tests von mir sind in einer VM mit WIN 7 Home und WIN7 Ultimate gemacht.
    Kumpel hat zwei Bildschirme, mit WIN 8

    Hab jetzt ein alten Lapi ausgepakt mit WIN XP, dort ist der Versatz nicht da, jedoch funktioniert der Bild Vergleich nicht, mach ich die Bilder in Paint auf vergrössere die, sehen die absolut gleich aus...Vielleicht Farbschema in WIN 7/8 zu XP? Kommt jetzt noch dazu 😮

    Das ist so was von unlogisch echt ma... durch dreh...

    Wo ist hier der Wurm drin, wer den findet geb ich ein Essen aus 😉



  • Du erstellst einen neuen Canvas und übergibst den Handle der Form.

    TCanvas* Canvas = new TCanvas(); 
    Canvas->Handle = GetDC(Form1->Handle); 
    ...   
    Image1->Picture->Bitmap->Canvas->CopyRect(Ziel, Canvas, Quelle); 
    ...
    

    Ich könnte mir vorstellen das evtl. die verschiedenen Betriebssysteme evtl. andere "Default" Werte haben und es so zu unterschieden kommt.

    Warum erstellst du ein neues Canvas und verwendest nicht gleich das deiner Form?

    TCanvas* Canvas = Form1->Canvas; 
    ...   
    Image1->Picture->Bitmap->Canvas->CopyRect(Ziel, Canvas, Quelle); 
    ...
    


  • Damit bringt er mir ein ntdll.dll Adress Fehler...

    Aber den Ansatz werd ich heute noch bissl weiter verfolgen, danke.



  • Scalierung schrieb:

    Warum erstellst du ein neues Canvas und verwendest nicht gleich das deiner Form?

    Vermutlich deshalb, weil man das nur im WM_PAINT-Handler verwenden darf.



  • audacia schrieb:

    Scalierung schrieb:

    Warum erstellst du ein neues Canvas und verwendest nicht gleich das deiner Form?

    Vermutlich deshalb, weil man das nur im WM_PAINT-Handler verwenden darf.

    Also

    Form1->Canvas
    

    rein zeichnen ja raus nein...
    Übrigens

    GetWindowDC
    

    für mehrere Monitore brings auch nicht...



  • Also das man Canvas nur im WM_PAINT verwenden darf wär mir neu.

    http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Graphics_TCanvas_CopyRect.html

    Ich glaub du hast noch einen Fehler in

    bmp1->Canvas->CopyRect(bmp1->Canvas->ClipRect, Canvas, Quelle);
    

    Ich kann mir nicht vorstellen das deine Zielposition auf der Form wirklich bmp1->Canvas->ClipRect sein soll.



  • In den beiden Zeilen hier wird der Form doch was zugewiesen, nicht entnommen... oder sehe ich das falsch...

    Form1->Canvas->BrushCopy(MyRect, Bitmap.get(), MyRect, clBlack);
      Form1->Canvas->CopyRect(MyOther, Bitmap->Canvas, MyRect);
    

    Der ntdll.dll Fehler kommt ja nicht mal zu der Code Zeile mit ClipRect, der kommt schon bei der Aufnahme der Bilder und Koords...

    Die Funktion an sich funktionier ja, wenn ich auf den anderen Systemen eine neue Koordinaten&Bild Aufnahme mache und diese dann abrufe läufts.
    Doch ist doch nicht der Sinn der Sache Koordinaten und Bilder für zich verschiedene Systeme zu hinterlegen, hab ja nicht alle und müsste zu den leuten die sie haben...

    bin auch felsenfest davon überzeugt das hier Default System unterschide gibt, habe schon versucht die user32.dll und gdi32dll mitzuliefern von WIN XP die Version. Doch auch nicht die Lösung.

    Hab ja schon mal gefragt wie bringe ich die Default werte im Programm mit, die die Standart Werte nur im Programm System übergreifend ignorieren?

    Doch zu erst müsste der Grundsätzliche Unterschied erst mal erkannt werden, meiner seits ist der mir nicht klar.

    Zwei dinge sind insofern kla, die Koordinaten fallen in den Unterschied hinein und neuergings (anscheinend) der Farbdastellungs Unterschied zu WIN XP(erst mal zweit drangig).

    Was ist der Grund dieser Koordinaten unterschiede? kann doch nur aus der Rechnung von Screen und TRect kommen... oder sehe ich das falsch?



  • Scalierung schrieb:

    Also das man Canvas nur im WM_PAINT verwenden darf wär mir neu.

    Stimmt, das ist Quatsch. Ich dachte, daß TControlCanvas intern BeginPaint() benutzt, aber es verwendet GetDC() , und das geht auch außerhalb von WM_PAINT.



  • OK das problem liegt wohl an IE Verions Unterschied von 8 zu 9<
    Für XP gibts nur den 8ter!?

    Der TWebBrowser verwendet die ActiveX Componente des IE's bei der Ver. 8 hat der Browser dann ein Border von 4Pixel, in den neueren nur 2Pixel. http://blogs.msdn.com/b/ie/archive/2010/08/23/making-sites-look-their-best-in-standards-mode.aspx

    So wie es aussieht bleibt nur die ActiveX Componente von Mozilla zu verwenden http://www.iol.ie/~locka/mozilla/control.htm oder das Programm in Delphi zu schreiben wo man die Borders ausschalten kann. (Was ich so über google an Infos raus hab)

    Oder weiss hierzu jemand noch eine andere Möglichkeit?

    Schon mal Danke an die Hilfe, hätte das vielleicht noch mit dem WebBrowser erwähnen sollen 🙄

    Wünsche ein schönes WE!



  • WebBrowser Wie Was Wo ....

    Was hat dass mit den ganzen was du uns gezeigt zu tun?

    Ich bin konfuse!



  • Scalierung schrieb:

    WebBrowser Wie Was Wo ....

    Was hat dass mit den ganzen was du uns gezeigt zu tun?

    Ich bin konfuse!

    Die Bilder werden im Browser dagestellt und da das der IE mit seinem Layout ist den der TWebBrowser benutzt als AxtiveX Komponente, kommt daher auch der unterschied zu der Positionierung der Bilder.

    Weil die Version 8 ein anderen Border hat als der 11ver, sind die Bilder immer versetzt gewesen.


Log in to reply