Du meinst in eine Hidden TextBox. Da kann man nicht reinklicken. Du kannst die HTML Seite analyisieren und das mit POST oder GET schicken, so wie es die Webseite wollte. Klappt zwar komischerweise auch nicht immer, aber in den meisten. Kommt auf die Webseite an.
Prinzipiel gehts ganz einfach, mal per Google zusammengesucht.
[DllImport("user32.dll")]
static extern bool InvertRect(IntPtr hDC, [In] ref Rectangle lprc);
[DllImport("user32.dll")]
static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool InvalidateRect(IntPtr hWnd,IntPtr lpRect, bool bErase);
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
public static extern IntPtr GetDesktopWindow();
public void inv()
{
Rectangle workArea = Screen.PrimaryScreen.WorkingArea;
IntPtr d = GetDesktopWindow();
// Desktop repaint, gegen schlieren
InvalidateRect(IntPtr.Zero, IntPtr.Zero, true);
// Desktop erfassen
IntPtr dc = GetWindowDC(d);
// Invertieren
InvertRect(dc, ref workArea);
// DC wieder freigeben
ReleaseDC(d, dc);
}
Das müsstest du dann per Timer aufrufen lassen. Ist zwar net gerade effizient aber es geht. Auch ohne Adminrechte.
Das nennt man allgemein Spline (mehrere an einander gereite Kurvenstücke). Speziel gibt es in Graphics DrawBezier. Man brauch nur 4 Punkte um eine Kurve zu bestimmen. Nur weis ich nicht was du mit sanft meinst. Kurve ist Kurve 🙂
@dr4g0n76
Ich meine das zwei Zeilen das selbe tun.
public void Test()
{
// Get a Graphics object associated with the screen.
bm = new Bitmap(this.m_strPath);
this.pictureBox1.Image = bm;
}
Hab nun eine Lösung gefunden, die einzige im Netz🙂
public void CaptureControl(PictureBox dstPic,Bitmap srcBmp)
{
Bitmap dstBmp = new Bitmap(dstPic.Image);
// Src anpassen
Graphics gSrc;
Graphics clientDC = this.CreateGraphics();
IntPtr hdc = clientDC.GetHdc();
IntPtr memdc = CreateCompatibleDC(hdc);
SelectObject(memdc, srcBmp.GetHbitmap());
gSrc = Graphics.FromHdc(memdc);
clientDC.ReleaseHdc(hdc);
Graphics gDst = Graphics.FromImage(dstBmp);
// dst anpassen
IntPtr dcSrc = gSrc.GetHdc();
IntPtr dcDst = gDst.GetHdc();
BitBlt(dcDst, 0, 0, 100, 100, dcSrc, 0, 0, TernaryRasterOperations.SRCCOPY);
DeleteDC(memdc);
gSrc.ReleaseHdc(dcSrc);
gDst.ReleaseHdc(dcDst);
DeleteObject(hBmp)
pictureBox1.Image = dstBmp;
}
Ich finde es zwar komisch das man die PictureBox noch zuweisen muss, aber naja es geht so erstmal. Damit schein nun diese Funktion auch der Flaschenhals geworden zu sein, obwohl diese die schnellste sein sollte 😦
P.S. Ich benutze eine Funktion die wie oben und noch Argumente die ich an BitBlt weiterleite um weniger im Code ändern zu müssen.
Danke, das geht wirklich!
Edit:
Seh grad das da beschissen wurde, das geladene Bitmap wird einfach der PictureBox zugewiesen. Wenn ich BitBlt auskommentiere passiert das selbe! Also leider keine Lösung!
Die Signaturen sind hier aus dem Forum und von pinvoke.
/// <summary>
/// Performs a bit-block transfer of the color data corresponding to a
/// rectangle of pixels from the specified source device context into
/// a destination device context.
/// </summary>
/// <param name="hdc">Handle to the destination device context.</param>
/// <param name="nXDest">The leftmost x-coordinate of the destination rectangle (in pixels).</param>
/// <param name="nYDest">The topmost y-coordinate of the destination rectangle (in pixels).</param>
/// <param name="nWidth">The width of the source and destination rectangles (in pixels).</param>
/// <param name="nHeight">The height of the source and the destination rectangles (in pixels).</param>
/// <param name="hdcSrc">Handle to the source device context.</param>
/// <param name="nXSrc">The leftmost x-coordinate of the source rectangle (in pixels).</param>
/// <param name="nYSrc">The topmost y-coordinate of the source rectangle (in pixels).</param>
/// <param name="dwRop">A raster-operation code.</param>
/// <returns>
/// <c>true</c> if the operation succeeded, <c>false</c> otherwise.
/// </returns>
[DllImport("gdi32.dll")]
static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth,
int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);
public enum TernaryRasterOperations:uint
{
SRCCOPY = 0x00CC0020, /* dest = source*/
SRCPAINT = 0x00EE0086, /* dest = source OR dest*/
SRCAND = 0x008800C6, /* dest = source AND dest*/
SRCINVERT = 0x00660046, /* dest = source XOR dest*/
SRCERASE = 0x00440328, /* dest = source AND (NOT dest )*/
NOTSRCCOPY = 0x00330008, /* dest = (NOT source)*/
NOTSRCERASE = 0x001100A6, /* dest = (NOT src) AND (NOT dest) */
MERGECOPY = 0x00C000CA, /* dest = (source AND pattern)*/
MERGEPAINT = 0x00BB0226, /* dest = (NOT source) OR dest*/
PATCOPY = 0x00F00021, /* dest = pattern*/
PATPAINT = 0x00FB0A09, /* dest = DPSnoo*/
PATINVERT = 0x005A0049, /* dest = pattern XOR dest*/
DSTINVERT = 0x00550009, /* dest = (NOT dest)*/
BLACKNESS = 0x00000042, /* dest = BLACK*/
WHITENESS = 0x00FF0062, /* dest = WHITE*/
};
[DllImport("gdi32.dll", ExactSpelling = true)]
internal static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll", ExactSpelling = true)]
internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll", ExactSpelling=true)]
internal static extern bool DeleteObject( IntPtr hgdiobj);
Hab nun mal in dem Support Artikel von MS gestöbert. Diese Funktioniert auch nur ist mir nicht klar warum in bitblt hdcScreen und hdcCompatible benutzt werden obwohl doch beides vom Desktop Fenster abstammen!
IntPtr hdcScreen = GetDC(GetDesktopWindow());
IntPtr hdcCompatible = CreateCompatibleDC(hdcScreen);
Seh ich richtig das GetDC der Win32 das selbe ist wie GetHdc von Graphics?
Kann es sein das es ein Problem gibt wenn mein Bild 24 Bit RGB ist, da im Deskop Beispiel 32 BitRGB rausgekommen ist.
Hi, ich portiere gerade ein altes Projekt. Dieses arbeitet mit BitBlt. Da DrawImage zu langsam ist, und mir die Zeit fehlt mich da reinzuarbeiten wollt ich die BitBlt Funktion wieder nehmen. Mein Problem ist egal was ich BitBlt gebe es kommt immer schwarz heraus!
private void button1_Click(object sender, EventArgs e)
{
Bitmap b = new Bitmap(m_strPath);
if (pictureBox1.Image == null)
{
pictureBox1.Image = new Bitmap(b.Width, b.Height, b.PixelFormat);
}
Graphics bmp = Graphics.FromImage(b);
Graphics pic = Graphics.FromImage(pictureBox1.Image);
Graphics form = this.CreateGraphics();
IntPtr bmpHdc = bmp.GetHdc();
IntPtr picHdc = pic.GetHdc();
IntPtr frmHdc = form.GetHdc();
IntPtr bmpDC = CreateCompatibleDC(bmpHdc);
IntPtr picDC = CreateCompatibleDC(picHdc);
IntPtr frmDC = CreateCompatibleDC(frmHdc);
IntPtr hbmOld = SelectObject(bmpDC, b.GetHbitmap());
// auf pic
bool bpic = BitBlt(picDC, 0, 0, b.Width, b.Height, bmpDC, 0, 0, TernaryRasterOperations.SRCCOPY);
// auf Form
bool bfrm = BitBlt(frmDC, 0, 0, b.Width, b.Height, bmpDC, 0, 0, TernaryRasterOperations.SRCCOPY);
SelectObject(bmpDC, hbmOld);
DeleteObject(bmpDC);
bmp.Dispose();
pic.Dispose();
form.Dispose();
Text = bpic.ToString() + " - " + bfrm.ToString();
}
Leider funktioniert das so nicht. Farbe ist 24Bit RGB, doch das kann es doch net sein. Das gleiche Ergebnis bekommt ich wenn ich einfach vom Graphics das Hdc übergebe. Bitblt bringt immer true zurück!
Der unterschied zwischen der obigen und er nur Hdc Version:
Ich hoffe Ihr habt auch das Problem, um mir zu helfen!
Auf http://www.fun-soft.de/showtopic.php?threadid=18936 wird gemeint das hier die Header Cpp Trennung nicht für Templates gilt.
Kann das jemand bestätigen.
Hi,
ich habe eine Klasse geschrieben und wollte diese in ein Template umwandeln, gesagt getan. Doch danach ging das teilen in mehrere Dateien nicht mehr!
Fpu.h
# ifndef _FPU_H_
# define _FPU_H_
template <class T, int P>
class Fpu
{
public:
Fpu();
};
#endif
Fpu.cpp
#include "Fpu.h"
template <class T, int P>
Fpu<T,P>::Fpu()
{
}
Wöllt ich nun Fpu<int,3> k; schreiben kommt immer der Fehler:
Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __cdecl Fpu<int,3>::Fpu<int,3>(void)" (??0?$Fpu@H$02@@QAA@XZ)" in Funktion "WinMain". Main.obj
doch schreib ich alles in den Header gehts! Ist das bei Templates allgemein so?
scheine eine lösung gefunden zu haben:
./definition/property[@name='Type' and @value='A' and count(../object) = 0]/../property[@name='Bmp' and @value=20]
Kann das jemand bestätigen, vom denken her?
Hi, ich habe eine xml, wo ich einfach alle tags haben will wo zwei attribute übereinstimmen.
bsp xml:
<definition>
<property name="Type" value="A>
<property name="Bmp" value="20>
..
</definition>
xpath:
./definition[./property/@name='Type' and ./property/@value='Ani' and count(../object) = 0][./property/@name='BitmapIndex' and ./property/@value='0']
Hier sollt das Attribut Type=A und Attribut Bmp=$position sein. Doch da es mehrere property elemente gibt kann auch irgend ein anderes name Attribut diesen value haben.
Gibt es da ne Möglichkeit?
Hi,
ich habe eine Bezier Spline. Und darauf soll sich ein Bild fortbewegen. Das problem dabei ist aber das je nach dem in welche Richtung der Spline geht sich das Bild drehen soll, so als ob ein Auto drauf lang fährt. Das funktioniert auch, nur eben das das Bild immer hin und her ruckelt. Das liegt sicher auch mit daran das ich zur Zeit nur den nächsten Pixel auswerte und an dem Spline an dem ich das teste nur 3 Winkel geliefert werden.
Derzeitiger Alg:
Habt ihr eine Idee anhand welcher Werte man das noch besser auswerten kann? Es kann auch ganz anders sein, es sollte halt nur smooth aussehen.
Achja, ich habe alle Bilder im abstand von 11,25 °, das sind 32 Stück, da kann man sich dann den smooth grad vorstellen.
Danke, herbivore, habs grad getestet und es geht! Wenn ich mal Zeit hab, werd ich dann weiter machen.
Na ein UserControl hat doch die Eigenschaft "Name", diese ist doch auch eindeutig! Du musst halt nur wissen wie der Name des jeweiligen UserControls ist. Das ist zwar nicht gerade sauber, aber es soll bei Dir sicher nur funktionieren.
Den Namen der zwei Instanzen kriegst du doch mit .Name
Es dabei nicht um Vista. Ab XP sollte für die Breite ja Mehrnutzer Betrieb möglich sein. Ich nutze XP, das sollte aber egal sein.
naja gut, hast mich überzeugt mit den hardlink,
http://bw11.ch/hardlink_windows.html hat mich dann überzeugt, der letzte Abschnitt.
Doch wie ich gerade sehe, benötigt diese tool Admin rechte, das ist schlecht, mit der neuen Philosophy von Mehrbenutzerbetrieb ohne Adminrechte.
Der zusatz soll gut sein zum suchen. Anhand von Stichworten die ich hinterlegt habe, oder sogar texte, die ich ständig ändern kann.
Hi,
mir schwebt schon seit längeren ein Archiv-tool vor in das ich meine Dateien hineinpflegen kann mit Stichworten, und in einem Baum z.b
main
->bilder
-> fun
->märz 2007
-> aprill 2008
-> Programmierung
-> Softwaretechnik
-> C#
-> C++
-> PHP
-> Asm
-> nasm
usw.
doch das ganze hätte keinen Sinn, wenn man man Dateien, oder ganze Dateiansammlungen mit Verzeichnissen nicht in mehrere Kategorien in den Baum einsortieren könnte.
Bsp.: ein lustiges Bild über Softwaretechnik, würde in Bilder -> fun, und auch in Programmierung-> Softwaretechnik passen, daher sollte es in beiden sein. Das ist auch nicht das Problem dies in xml zu machen. Doch mein problem ist das Physikalische der Dateien, bzw Verzeichnisse.
Entweder mach ich den Baum auch physikalisch:
Oder, willkührliche Index-Zahlen als Verzeichnis:
Hab ihr einige abstrakte, oder gut organisierte ideen?
Wie ihr gelesen habt wäre die Datenbank ein Xml File.
Ja, mit ummünzen meint ich, da ich es ja ein wenig anders brauch. Ich verrat mal wofür es gebraucht wird.
Ich habe KollisionsRechteck, und dieses zufällig mit Explosionen füllen die eine gewisse Rechteckgröße haben. Seh schon werd doch mein mir gerade vorschwebenden alg. verwenden.
Zufällige Explosion auswählen die nicht übermäßig breiter oder höher ist als kollisionsrechteck
dieses zufällig platzieren
dieses Rechteck abziehen und viele kleine Rechtecke erzeugen. und bei 1. weiter machen
Mh, klingt ganz gut, nur auf Rechtecke und Koordinaten ummünzen ist sicher auch net das wahre oder hab ich was übersehen.
Hab in einem Forem das "Plainsweep-Paradigma" gefunden, jedoch fand ich dazu nix bei google, kennt das einer?
Frage zu Knapsack Problem:
Würde das Problem auch als gelöst gelten, wenn die List der Gegenstände mit Gewicht nach ihrem Wert in einer Liste sortiert sind?
Kennt jemand einen Algorithmus um ein Rechteck mit verschieden großen Rechecken (wo die größe und anzahl der Möglichkeiten bekannt ist) per Zufall zu füllen? Dabei darf das Rechteck auch etwas überschritten werden und es dürfen auch kleine Lücken vorkommen. Kennt da jemand einen Algorithmus?
Danke, damit geht es auf anhieb.
Mir ist nun dabei aufgefallen, das das Sendkey Funktioniert wenn man Cursor.Position setzt. Doch eigentlich sollte es laut MSDN auch nur mit der Funktion gehn. Zumal es bei mir nicht immer funktioniert, das kann aber auch dran liegen weil ich immer gleich zur alten Position zurück springe.
Das Problem liegt daran das SendMessage immer 0 zurück liefert, das bedeutet ja das es nicht verarbeitet wird. Kann das auch an der Anwendung liegen?
Hi,
zu erst, ja ich hab gesucht! Was ich will ist entweder auf eine beliebige Stelle des Bildschirms klicken oder direkt an eine Stelle in einem Fenster auch wenn es nicht sichtbar ist!
private const int MK_LBUTTON = 0x0001;
private const uint WM_LBUTTONDOWN = 0x0201;
private const uint WM_LBUTTONUP = 0x0202;
[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hwnd, uint wMsg,
int wParam,
int lParam);
public void MouseClicken(IntPtr windowhandle, int x, int y)
{
SendMessage(windowhandle, WM_LBUTTONDOWN, MK_LBUTTON, y * 0x10000 + x);
SendMessage(windowhandle, WM_LBUTTONUP, MK_LBUTTON, y * 0x10000 + x);
}
Ich bin mir z.B. mit MK_LBUTTON nicht sicher, da in andere Foren sowas nie benutzt wurde obwohl es in der MSDN steht. Ansonsten weis ich nicht woran es liegen könnte. Ach ist es eigentlich egal ob die WM int oder uint sind, ebenso bei MK da es ja eigentlich konvertiert wird oder?
Bitte helft mir und stellt gemeine Fragen.
Ja ich weis das das verschenderisch ist, aber der Code war auch nur zum Testen, bzw. zum rausfinden obs geht.
Hab's nun gefunden ohne Rechnen, bzw. mit den Erkentnissen der unvollständigen Rechnung.
x, y und delta sind vorberechnet vom normalen Beresenham.
void bresenham_kreis_1 (int r) //nur für radius 50
{
double delta; int x, y; x = 35; y = 34; delta = 18.25;//(5.0 / 4.0) + r;
string s = "";
while (x >= 0)
{
this.CreateGraphics().DrawRectangle(Pens.Green, 200 + y, 100 + x, 0.1f, 0.1f);
this.CreateGraphics().DrawRectangle(Pens.Red, 200 + -y, 100 + x, 0.1f, 0.1f);
this.CreateGraphics().DrawRectangle(Pens.Red, 200 + y, 100 + -x, 0.1f, 0.1f);
this.CreateGraphics().DrawRectangle(Pens.Red, 200 + -y, 100 + -x, 0.1f, 0.1f);
this.CreateGraphics().DrawRectangle(Pens.White, 200 + x, 100 + y, 0.1f, 0.1f);
this.CreateGraphics().DrawRectangle(Pens.Red, 200 + x, 100 + -y, 0.1f, 0.1f);
this.CreateGraphics().DrawRectangle(Pens.Red, 200 + -x, 100 + y, 0.1f, 0.1f);
this.CreateGraphics().DrawRectangle(Pens.Red, 200 + -x, 100 + -y, 0.1f, 0.1f);
System.Threading.Thread.Sleep(100);
Application.DoEvents();
if (delta > 35)
{
delta -= 2 * (x-1) + 3.0;
x--;
}
else
{
delta -= 2 * (x-1) - 2 * (y+1) + 5.0; x--;
y++;
}
}
}
tmpCondition ist gleich x bei der Initialisierung und ist ab da konstant.
dx und dxy musst ich suchen mit Hilfe des normalen Bresenham.
(Hier ist irgendwo noch ein Fehler)
private bool calculatePointReverse()
{
if (m_currentDescription.x > 0)
{
m_currentDescription.x--;
if (m_currentDescription.d > m_currentDescription.tmpConditon)
{
m_currentDescription.d -= m_currentDescription.dx;
m_currentDescription.dxy -= 2;
m_currentDescription.dx -= 2;
}
else
{
m_currentDescription.d -= m_currentDescription.dxy;
m_currentDescription.dxy -= 4; m_currentDescription.y--;
m_currentDescription.dx += 2;
}
return true;
}
return false;
}
Ich hoffe ihr versteht das.
Ja, das kann sein. Nur ist laut meinen Erinnerungen das Ergebnis nicht gut genug.
Kennt jemand eine Webseite wo der Bresenham so hergeleitet wird das man es auch versteht. Da ich bisher entweder herleitung gefunden habe die es übertreiben, oder welche wo ich nur an einer Stelle nicht weiter kam.
Dies war z.b. dieses Script auf Seite 15 unter "Bilde für die Inkremente 2.-te Differenzen"
die 4. schwarzen Flächen. dort ist einmal delta südost und delta ost, beide sind komischerweise gleich. Ich bin mir nicht sicher ob das delta von xx+ yy = r*r oder von der gleichung die auf Seite 14 unter der Impliziten kreis gleichung steht.
Vielleicht weis ja einer damit was anzufangen. Zumal das nur noch ein schritt ist. Und als ich immer gerechnet hatte waren immer x oder y übrig auch bei dem original Algorithmus.
Ja, das Zeichnen schon, jedoch wird der Algorithmus in 2 Sprachen verwendet. Die zweite ist C++ ohne .NET und mit vielen Einschränkungen. Jedenfalls brauch ich keine ganze Ellipse sonder immer nur einen Punkt hinter einander weg, und das zu diskreten Zeiten. So das diese abgelaufen werden kann.
Hi, ich habe auch gerade das Problem mit zu langem Pfad. Doch wie ermittelt man eine Dateigröße ohne ein Handle zu haben? Für GetFileSize wird ein Handle benötigt. Da man aber über FileStream kein Handle erstellen kann, und ich keine API gefunden habe, würde ich es gern von euch erfahren.
Please!!!!!
EDIT:
Sorry, hat sich erledigt, steht ja im letzen Post. Mich wundert nur das man so eine quälende Exception erfunden hat!
Was ich komisch finde das der IE7 selbst eine art HTML Seite abruft mit Dateiauflistung, und das Webbrowser Control die Dateien wie im Explorer anzeigt.
Komisch oder?
Hallo TimoS,
du kannst das hier zum selbstzeichnen nehmen http://www.codeproject.com/useritems/VistaButton.asp . Da sind Hover Effekte und runde Kanten.
Oder hier Glüh Effekte http://www.codeproject.com/vb/net/glowbutton.asp .
Ich merk grad das das gar nicht bresenham ist sondern die methode von Horn die ich benutze. Obwohl hier http://www-lehre.inf.uos.de/~cg/2000/Postscript/skript01-04.pdf steht das es Bresenham sein soll.
Ich hatte sowas doch schob oben versucht jedochgabs da keine Abbruchbedingung und das Ergebnis ist auch abweichend.
Mein neuer ansatz ist nun:
private bool calculatePointReverse()
{
if (m_currentDescription.y >= m_currentDescription.x)
{
if (m_currentDescription.d < 0)
{
m_currentDescription.d += m_currentDescription.dx;
m_currentDescription.dxy += 2; m_currentDescription.y--;
}
else
{
m_currentDescription.d += m_currentDescription.dxy;
m_currentDescription.dxy += 4;
}
m_currentDescription.dx += 2;
m_currentDescription.x++;
return true;
}
return false;
}
Wo nur das y an einer anderen Stelle geändert wird.
Jedoch scheint das auch abzuweichen und es scheint nicht auf knopfdruck rückwärts zeichnen zu lassen. Also das ich die vorwärtszeichnung automatisch in eine rückwärtszeichnung umwandeln kann.
Na der Bresenham tut rechts in der vertikalen Mitte. Von da aus tut er nach oben malen. Dies gilt für die anderen Teile auch. Ich will aber von oben nach unten malen. Also den Kreis in die andere Richtung zeichnen.
Wenn ich das benutze kommt dann immer nur ein Teil zur Anwendung, welche dann hintereinander gesetzt werden. Somit kann man Kurven in alle Richtungen und biegungen zeichnen. Also brauch ich nur einen Bresenham Alg der den Kreis andersrum zeichnet, bzw. die Teilstücke.
Mehrere Teilstücke sollen eine länger Strecke mit Kurven darstellen. Um dies aber bewerkstelligen zu können muss die kurve in beide Richtung biegbar sein, aber bei nur einer Bewegungsrichtung im Kreis, würde man immer an einem Kreis enden. Also muss ich den Kreis auch anders rum zeichnen können.
Ich weis selbst das es die im Framework gibt. Es steht außer Frage das es für Dich nicht sinnig erscheint. Es geht aber um Optimierung, und da ist der am besten, da keine einzig Multiplikation. Bitte jetzt net kommen, das alle PC schon schnell genug dafür sind. PCs schon, aber ganz kleine nicht.
Es ein quasie sehr vereinfachter Spline gezeichnet werden, um eine Bahn zu haben um etwas abzulaufen, das muss natürlich auch umgekehrt gehen, daher.
Microsoft.WindowsMobile.DirectX ?
Ich wollte den Kreise per Bresenham rückwärts zeichen lassen, als der Algoirthmus es vorgibt. Dabei sollt es eigentlich keine Pixel änderungen geben.
m_currentDescription enhält die Parameter x,y,d,dx,dxy.
Es wird immer ein Punkt berechnet, gezeichnet und dann wieder berechnet. Also keine querrechnerrei, das man alles vorrechnet!
Algorithmus vorwärts für einen Punkt:
private bool calculatePoint()
{
if (m_currentDescription.y >= m_currentDescription.x)
{
if (m_currentDescription.d < 0)
{
m_currentDescription.d += m_currentDescription.dx;
m_currentDescription.dxy += 2;
}
else
{
m_currentDescription.d += m_currentDescription.dxy;
m_currentDescription.dxy += 4; m_currentDescription.y--;
}
m_currentDescription.dx += 2;
m_currentDescription.x++;
return true;
}
return false;
}
Algoritmus rückwärts für einen Punkt:
private bool calculatePointSp()
{
if (m_currentDescription.y >= m_currentDescription.x - 1)
{
m_currentDescription.x--;
m_currentDescription.dx -= 2;
if (m_currentDescription.d >= 0)
{
m_currentDescription.dxy -= 2;
m_currentDescription.d -= m_currentDescription.dx;
}
else
{
m_currentDescription.dxy -= 4; m_currentDescription.y++;
m_currentDescription.d -= m_currentDescription.dxy;
}
System.Windows.Forms.MessageBox.Show("x:" + m_currentDescription.x + "y:" + m_currentDescription.y + "d:" + m_currentDescription.d + "dx:" + m_currentDescription.dx + "dxy:" + m_currentDescription.dxy);
return true;
}
return false;
}
Das Problem ist nun das es keine Abbruchbedingung gibt! Es berechnet ins unendliche. Vielleicht hab ich den Alg ja falsch umgestellt, bzw etwas außer acht gelassen.
Hi Zebes,
ich habe es genauso gemacht als ich Items mit Icons vom Explorer geladen habe. Das DoubleBuffer hat bei mir geholfen. Ich benutze weder BeginUpdate noch SuspendLayout! Aber bei mir aktualisiert jedes Element sich selbst, sprich das Icon.
Und da System32 bei mir 1900 Elemente hat, kann ich mit Sicherheit sagen, das es Funktioniert.
Ist nun die Frage wie du die Daten einfügst? Ich benutze Invoke, obwohl Herbivore immer meint BeginInvoke ist besser.
Ein auszug wäre angebracht.
Also mit 0 als width gehts auch net!
e.Graphics.DrawRectangle(new Pen(Color.Black, 0),...);
Kannst du uns die Lösung verraten?
Selbst damit werden 4 Pixel gezeichnet! Ebenso wenn die width==2 ist.
@PhilHol Das ist das was ich eigenlich net wollte. Trotzdem, thx.
Naja wäre net wenn du mir das noch sagen könntest wie?
Ich verwende es derzeit so, da werden 4 Pixel gezeichnet
e.Graphics.DrawRectangle(new Pen(Color.Black), m_drawPlace.Left + pNext.X, m_drawPlace.Top + pNext.Y, 1, 1);
Hi,
kennt jemand eine Möglichkeit auf ein Graphics Object, welches von einem Panel ist, einen Pixel zu setzen, da Rectangle Zeichen mindestens 4 Pixel setzt und linie mindestens 2.
Oder geht es nur über Image Zeichnen?
Jo, das klappt ja wirklich. Da ich KeyDown benutze und das auch schon mit dem Handled versucht hab.
Hi,
nach langem suchen an meinem Problem fand ich nun raus, das das Element mit dem Ersten Buchstaben selectiert wird wenn man den ersten Buchstaben drückt. Da alle bei mir den selben anfangsbuchstaben haben, hatte ich zu tun das problem zu lokalisieren. Da ich ein Item mit einem anderen Item austauschen will über Tastendruck, tritt dort das Problem auf. Weis jemand wie man das abschalten kann, oder steuern kann?
Hab nun noch ne Optimierung gemacht, das anhand der Erweiterung bei vielen das Icon nur einmal ermittelt werden muss. Damit läuft es jetzt richtig flüssig und füllt sich auch rasend.
Irgendwo das anstoßen:
List<string> items = new List<string>();
items.AddRange(Directory.GetDirectories(currentPath.LocalPath));
items.AddRange(Directory.GetFiles(currentPath.LocalPath));
threadParameter parameter = new threadParameter(items, currentPath.LocalPath);
itemFiller = new Thread(new ParameterizedThreadStart(FillList));
itemFiller.Start(parameter);
Die Thread Methoden:
delegate void addToList(ListViewItem item);
public void FillList(object path)
{
threadParameter parameter = (threadParameter)path;
foreach (string var in parameter.items)
{
FileSystemListViewItem item = new FileSystemListViewItem(var, null);
files.Invoke(new addToList(add), item);
item.findMyIcon();
}
}
public void add(ListViewItem file)
{
files.Items.Add(file);
}
Und das Item welchese selbst das Icon ermittelt:
public class FileSystemListViewItem : ListViewItem
{
private Uri fullpath;
public FileSystemListViewItem(string path, ListViewGroup group):base(group)
{
string lastEle = lastElement(path);
this.Text = lastEle;
fullpath = new Uri(path);
}
public void findMyIcon()
{
if (this.ListView == null) throw new InvalidOperationException("Muss einem ListView erst zugeordnet werden!");
string myKey = string.Empty;
string path = fullpath.LocalPath;
if (Directory.Exists(path))
{
myKey = "?Directory?";
}
else
{
FileInfo info = new FileInfo(path);
if (info.Extension == ".exe" || info.Extension == ".ico")
{
myKey = path;
}
else
{
myKey = info.Extension;
}
}
if (!this.ListView.SmallImageList.Images.ContainsKey(myKey))
{
Icon small = ExplorerIcon.getSmallIcon(path);
Icon large = ExplorerIcon.getLargeIcon(path);
if (this.ListView.InvokeRequired)
{
this.ListView.Invoke(new add(addIconToListView), small, large, myKey);
}
else
{
addIconToListView(small, large, myKey);
}
}
if (this.ListView.InvokeRequired)
{
this.ListView.Invoke(new setKey(setImageKey), myKey);
}
else
{
this.ImageKey = myKey;
}
}
delegate void add(Icon small, Icon large, string key);
delegate void setKey(string key);
private void addIconToListView(Icon small, Icon large, string key)
{
this.ListView.SmallImageList.Images.Add(key, small);
this.ListView.LargeImageList.Images.Add(key, large);
}
private void setImageKey(string key)
{
this.ImageKey = key;
} ...
Was mir jetzt noch nicht gefällt ist das mit der Liste erstellen für den Thread. Da dort, intern entwerder ein CopyTo oder eine while schleife abläuft die jedes Element einzeln hinzufügt.
Hat jemand eine Idee?
P.S. Ich benutze das außerhalb eines Threads um die IOException brauchbar abzufangen.
Also hab nun:
files.BeginInvoke(new ThreadStart(BeforeChange));
files.Invoke(new addIcons(addToImageList), ExplorerIcon.getSmallIcon(var), ExplorerIcon.getLargeIcon(var),var);
FileSystemListViewItem item = new FileSystemListViewItem(var, null);
files.Invoke(new setIcon(setToList), item, i++);
files.BeginInvoke(new ThreadStart(AfterChange));
und in BeforeChange ein SuspendLayout und ein Beginupdate, und in der anderen das End aquivalent. Das bringt so nix, werde wohl ableiten müssen.