kostenloser Webspace werbefrei: lima-city


Suche auf lima-city

  • in: Simple Frage zu Referenz in C++ und Qt

    geschrieben von darkpandemic

    Hallo sebastian-online,

    dein Problem im ersten Beispiel kommt folgendermaßen zustande:
    Die Zeile
    QString szItem = "Test";
    erzeugt ein QString-Objekt auf dem Stack, welche beim eintreten in die Funktion initialisiert wird. Damit auch alles wieder ordentlich aufgeräumt wird baut der Compiler am Ende der Funktion eine Destruktoraufruf ein.
    Hierbei ist zu beachten, dass QString für den Text Speicher auf dem Heap reserviert, welcher im Destruktor freigegeben wird.

    Der Bug ist dann die folgende Zeile:
    szItem = QString(szItemAnd);
    Hierbei wird ein neues/zweites QString-Objekt erzeugt und dieses als flache Kopie über szItem kopiert. Dabei wird insbesondere die Speicheradresse des Textes im Heap überschrieben. D.h. das erste und das zweite QString-Objekt verweisen jetzt auf den Text-Speicherbereich des zweiten QString-Objektes. Die Adresse des ersten Objektes ist verloren und man hat daher ein Memory-Leak.
    Der Compiler merkt aber, dass das zweite QString-Objekt nach dieser Zeile nicht weiter benötigt wird, weshalb er gleich nach dieser Zeile einen Destruktor-Aufruf für das zweite QString-Objekt einfügt.
    Jetzt verweist die Heap-Adresse des ersten QString-Objektes auf einen bereits freigegebenen Speicherbereich.
    Sofern ein Zugriff auf diesen Speicher nicht bereits zum Programmabsturz führt kommt es spätestens beim Verlassen der Funktion, wenn der Destruktor aufgerufen wird, dazu, weil dieser versucht den bereits freigegenenen Speicherbereich erneut freizugeben.

    Hier noch zwei Beispiele zur Illustration mit dem Debugger:
    1. Kein Problem:
    #include <iostream>
    
    using namespace std;
    
    class Test
    {
      public:
      Test(int i):value(i) {}
      Test(const Test& t):value(t.value) {}
      ~Test(){}
      int get() { return value; }
      void set(int i) { value = i; }
    	
      private:
      int value;
    };
    
    int main(int argc, char ** argv)
    {
      Test t = 3;	
      cout << t.get() << endl;	
      t = Test(4);
      cout << t.get() << endl;
      return 0;
    }

    2. Crash:
    #include <iostream>
    
    using namespace std;
    
    class Test
    {
      public:
      Test(int i) { value = new int[1]; value[0] = i;}
      Test(const Test& t) {value = new int[1]; value[0] = t.value[0];}
      ~Test(){ delete[] value; }
      int get() { return value[0]; }
      void set(int i) { value[0] = i; }
    	
      private:
      int * value;
    };
    
    int main(int argc, char ** argv)
    {
      Test t = 3;
      cout << t.get() << endl;
      t = Test(4);
      cout << t.get() << endl;
      return 0;
    }




  • in: [C#/C++] Fenster anderer Programme verstecken

    geschrieben von darkpandemic

    Hallo dmm,

    mit Hilfe der Funktion EnumDesktopWindows() kannst Du die Handles aller top-level Fenster abfragen.
    Wenn Du diese hast, dann kannst Du mit Hilfe der ShowWindow() Funktion die Fenster verstecken und wieder sichtbar machen.
    Hier ist ein Beispiel in C++:
    #include <vector>
    #include <iostream>
    #include <cstring>
    #include <Windows.h>
    
    using namespace std;
    
    static BOOL CALLBACK enum_window_callback(HWND hwnd, LPARAM l_param)
    {
      char classname[256];
      vector<HWND> * window_handles;
      
      /* Exclude hidden windows from list: */
      if(!IsWindowVisible(hwnd))
        return TRUE;
    
      /* Exclude taskbar and start button from list: */
      if( !GetClassName(hwnd, classname, sizeof(classname)) || 
          !strcmp(classname, "Shell_TrayWnd") ||
          !strcmp(classname, "Button"))
        return TRUE;
    
      /* Append top level window handle to list */
      window_handles = (vector<HWND>*)l_param;
      window_handles->push_back(hwnd);
    
      return TRUE;
    }
    
    int main(int argc, char ** argv)
    {
      vector<HWND> window_handles;
    
      EnumDesktopWindows(NULL, enum_window_callback, (LPARAM)&window_handles);
    
      /* Hide top level windows: */
      for(unsigned int i=0; i<window_handles.size(); i++)
        ShowWindow(window_handles[i], SW_HIDE);
    
      /* Wait for 5 seconds: */
      Sleep(5000);
    
      /* Show top level windows: */
      for(unsigned int i=0; i<window_handles.size(); i++)
        ShowWindow(window_handles[i], SW_SHOW);
    
      return 0;
    }
  • in: Ausbreitung von Gravitation

    geschrieben von darkpandemic

    Hallo drafed-map,

    die folgende Aussage ist richtig:
    drafed-map schrieb:
    ...
    Wenn sich Gravitation nur mit Lichtgeschwindigkeit ausbreitet, soll das heißen, dass MA nicht Richtung MR gezogen wird, sondern dort hin, wo MR vor beispielsweise einer Milliarde Jahren war?
    ...
    Wenn MR ungefähr eine Milliarde Lichtjahre von MA entfernt ist, dann kann MA nur wissen/merken was vor einer Milliarde Jahren mit MR los war.

    Kleine Anmerkung zur zweiten Frage:
    Wenn sich MR nur geradlinig bewegt, werden keine Gravitationswellen erzeugt. 'Gravitationswelle' bedeutet ja, dass die Gravitation periodisch anwächst und wieder schwächer wird. Sowas entsteht z.B., wenn eine anisotrope (=ungleichmäßig verteilt) Maßeverteilung rotiert.

    Und nun zur zweiten Frage:
    Einstein hat einerseits postuliert, dass träge Masse gleich der schweren Masse ist und andererseits gezeigt, dass die Masse eines Systems proportional zu seiner Gesamtenergie ist. Daraus folgt, dass die gesamte relativistische Masse auch gravitiert, was bedeutet, dass ein bewegtes Objekt ein stärkeres Gravitationsfeld besitzt als eines welches im System des Beobachters ruht (bei gleicher Ruhemasse).
    Wie sich die beobachtete Gravitation genau berechnet kann ich Dir aber leider nicht sage, da ich mich nie genauer mit allgemeiner Relativität auseinandergesetzt habe.
  • in: C# Polymorphismus mit Standardklassen

    geschrieben von darkpandemic

    Hallo friedsei,

    ironischerweise hat MouseEventArgs.Empty den Datentyp EventArgs, d.h. Du musst einen Cast einfügen:
    private void Button_Mouse_Down(object sender, MouseEventArgs e) {
        MouseDown(this, (MouseEventArgs)MouseEventArgs.Empty);
    }
    Aber eigentlich kannst Du auch die originalen Ereignisdaten weiterreichen, dann stehen diese auch im nächsten Handler zur Verfügung:
    private void Button_Mouse_Down(object sender, MouseEventArgs e) {
        MouseDown(this, e);
    }
    Das kann man bei allen anderen Ereignissen dann analog machen.
  • in: C# Polymorphismus mit Standardklassen

    geschrieben von darkpandemic

    Hallo friedsei,

    der erste Gedanke, der mir kam, als ich Dein Posting gelesen habe war der folgende:
    Mann kann ja eine Klasse 'MyControl' schaffe, die von Panel abgeleitet ist und in die man die gewünschten Controls einfach einbettet. Dann kann man beliebig viele Methoden, Properties und Member-Variablen hinzufügen und es sieht für den Benutzer wie ein das jeweilige normale Control aus.
    Da es ja quasi ein abgespeckter GUI-Editor werden soll, benötigt man auch nicht alle Properties und Eigenschaften des eingebetteten Controls sondern nur eine kleine Teilmenge davon. Bei einem Button wird es vermutlich reichen, wenn man den Text ändern kann und wenn man das Click-Event abfangen kann. Damit würde sich der Aufwand in Grenzen halten.
    Hier habe ich es mal ein wenig anprogrammiert:
    using System;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace MyControlTest
    {
      abstract class MyControl : Panel
      {
        protected Control embeddedControl;
    
        public string MyName { get; set; }
        public Control EmbeddedControl { get { return embeddedControl; } }
    
        public MyControl(Control ctrl)
        {
          embeddedControl = ctrl;
          ctrl.Location = new Point(0, 0);
          ctrl.Size = this.Size;
          ctrl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
          Controls.Add(ctrl);
        }
      }
    
      class MyLabel : MyControl
      {
        public MyLabel()
          : base(new Label())
        {
        }
    
        public override string Text
        {
          get
          {
            return ((Label)embeddedControl).Text;
          }
    
          set
          {
            ((Label)embeddedControl).Text = value;
          }
        }
      }
    
      class MyButton : MyControl
      {
        public new event EventHandler Click;
    
        public MyButton()
          : base(new Button())
        {
          Button btn = (Button)this.embeddedControl;
          btn.Click += Button_Click;
        }
    
        public override string Text
        {
          get
          {
            return ((Button)EmbeddedControl).Text;
          }
    
          set
          {
            ((Button)EmbeddedControl).Text = value;
          }
        }
    
        private void Button_Click(object sender, EventArgs e)
        {
          Click(this, EventArgs.Empty);
        }
      }
    
      class MyTextBox : MyControl
      {
        public MyTextBox()
          : base(new TextBox())
        {
        }
    
        public override string Text
        {
          get
          {
            return ((TextBox)EmbeddedControl).Text;
          }
    
          set
          {
            ((TextBox)EmbeddedControl).Text = value;
          }
        }
      }
    
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
    
          MyLabel lbl = new MyLabel();
          lbl.MyName = "Label";
          lbl.Location = new Point(0, 0);
          lbl.Size = new System.Drawing.Size(100, 24);
          lbl.Text = "Hallo";
          Controls.Add(lbl);
    
          MyButton btn = new MyButton();
          btn.MyName = "Schaltfläche";
          btn.Location = new Point(100, 0);
          btn.Size = new System.Drawing.Size(100, 24);
          btn.Text = "Welt";
          btn.Click += Button_Click;
          Controls.Add(btn);
    
          MyTextBox txt = new MyTextBox();
          txt.MyName = "Textfeld";
          txt.Location = new Point(0, 24);
          txt.Size = new System.Drawing.Size(100, 24);
          txt.Text = "Änder mich!";
          Controls.Add(txt);
        }
    
        private void Button_Click(object sender, EventArgs e)
        {
          MessageBox.Show("Juhu!");
        }
      }
    }
    Dann ist mir aber aufgefallen, das Deine Problemstellung dadurch vermutlich nicht wirklich gelöst wird.
    Dein Programm muss ja zwei Modi haben: Entwurfsmodus und Ausführungmodus.
    Für den Ausführungmodus ist das da oben ja in Ordnung, aber im Entwurfsmodus soll ein Button zwar wie ein Button aussehen, darf sich aber eigentlich nicht so verhalten. Stattdessen will man ihn verschieben und z.B. die Größe ändern können. D.h. man muss die MouseDown, MouseMove und MouseUp Events abfangen können um einen Drag zu ermöglichen. Das ist aber mit den Standardcontrols, wenn überhaupt, nur über schwierige Umwege machbar.
    Für den Entwurfsmodus müsste man eigentlich ein extra Control entwickeln, was die Designfunktionalität bereitstellt. Dann würde das was werden.
  • in: C# Polymorphismus mit Standardklassen

    geschrieben von darkpandemic

    Hallo friedsei,

    jetzt muss ich Dich leider ein wenig enttäuschen. Man muss sich halt entscheiden, ob man die statischen Erweiterungen nutzt, was einem die Events erhält oder ob man die Objekte kapselt und dadurch beliebige Member-Variablen einführen kann.
    Falls es keine Option ist den ControlHolder einfach mit einer getControl()-Methode auszustatten und das dann zur Installation der Event-Handler zu benutzen, dann kannst Du ja mal kurz beschreiben, welches Ziel Du eigentlich verfolgst.
    Vielleicht gibt es ja einen anderen Weg der Dein zugrunde liegendes Problem löst.
  • in: ASM: Problem mit C-Call pthread

    geschrieben von darkpandemic

    Hallo alle miteinander,

    an der Sache mit der Calling-Convention ist was dran.
    Ich habe nochmal rumgesucht um herauszufinden, wie diese unter 32-Bit Linux ist. Vermutlich ist aber die aufrufende Funktion für das Aufräumen des Stacks zuständig (siehe hier), d.h. die Funktion fkt sollte so eigentlich funktionieren. Ich habe die Funktion jetzt mal mit dem üblichen Kopf und Fuß ausgestattet. Vielleicht geht es ja dann:
    FORMAT elf
    PUBLIC main
    SECTION '.text' executable
     
    main:
        PUSH EBP
        MOV  EBP, ESP
    
        PUSH null
        LEA  EAX, ftk
        PUSH EAX
        PUSH null
        LEA  EAX, zgr
        PUSH EAX
        CALL pthread_create
        POP  EAX
        POP  EAX
        POP  EAX
        POP  EAX
     
        CALL fkt
     
        PUSH null
        LEA  EAX, zgr
        PUSH EAX
        CALL pthread_join
        POP  EAX
        POP  EAX
     
        PUSH [anz]
        LEA  EAX, msg
        PUSH EAX
        CALL printf
        POP  EAX
        POP  EAX
    
        LEAVE
        RET
     
    fkt:
        ; save EBP
        PUSH EBP
        ; load stack pointer to EBP
        MOV EBP, ESP
    
        INC [anz]
    
        ; set return value to 0
        XOR EAX, EAX    
        LEAVE
        RET
     
    EXTRN printf
    EXTRN pthread_create
    EXTRN pthread_join
    SECTION '.data'
    anz DD 0
    null DD 0
    msg DB "Anzahl der Aufrufe: %i",10,0
    zgr DD ?

    Bei
    REP STOSD
    kannst Du ja mal schauen, was in EAX steht. REP STOSD kopiert ja Daten von der Adresse auf die EAX zeigt und zwar sooft bis ECX 0 ist.

    Edit:
    Ich habe jetzt noch LEA-Befehle eingefügt. Dieser Befehl berechnet aus einem Offset die echte Adresse im Arbeitsspeicher. Nachdem der Assembler zu dem Zeitpunkt, an dem das Programm assembliert wird nicht wissen kann, welche Adressen Deine Daten und Funktionen später haben werden kann er eigentlich nur Offsets anstelle der absoluten Adressen pushen. Damit kann pthread_create() dann natürlich nichts anfangen.
    Merkwürdig ist aber, dass die meisten FASM-Beispiele etwas anderes suggerieren.
    Aber vielleicht geht es jetzt.
  • in: C# Polymorphismus mit Standardklassen

    geschrieben von darkpandemic

    Hallo friedsei,

    ich denke, dass Du unter 'drauflegen' meinst, dass Du die Ereignisse des gekapselten Controls abfangen kannst. Das geht leider nicht direkt.
    Aber ich hätte noch eine andere Idee, nämlich schlicht die Erweiterung von Control um die gewünschten Funktionen:
    public static class ControlExtensions
    {
        public static int getMyInt(this Control c)
        {
          return -1;
        }
    }
    Damit kannst Du dann folgendes machen:
    Button btn = new Button();
    TextBox txt = new TextBox();
    
    Console.writeLine("Button: " + btn.getMyInt() + "TextBox" + txt.getMyInt());
    oder aber:
    Control btn = new Button();
    Control txt = new TextBox();
    
    Console.writeLine("Button: " + btn.getMyInt() + "TextBox" + txt.getMyInt());
    Und Event-Handler kannst Du wie gewohnt einbauen.
    Der Nachteil ist aber, dass man keine neuen Member-Variablen einführen kann.
  • in: C# Polymorphismus mit Standardklassen

    geschrieben von darkpandemic

    Hallo friedsei,

    die folgende Klasse ermöglicht Dir zumindest die gewünschte Syntax:
    class ControlHolder
    {
        Control ctrl;
    
        public ControlHolder(Control c)
        {
            this.ctrl = c;
        }
    
        public static implicit operator ControlHolder(Control c)
        {
            return new ControlHolder(c);
        }
    
        public int get()
        {
            return -1;
        }
    }
  • in: ASM: Problem mit C-Call pthread

    geschrieben von darkpandemic

    Hallo toolz,

    die Argumente kann man auf keinen Fall weglassen, da die pthread_create() Funktion ja nicht wissen kann, dass Du das Argument weglässt. Daher wird sie immer vier Argumente vom Stack holen.
    Mein Arch hat den FASM jetzt leider auch nicht im Repo, dass ich es schnell testen könnte und eine offensichtlichen Fehler erkenne ich jetzt auch nicht :-(
  • in: ASM: Problem mit C-Call pthread

    geschrieben von darkpandemic

    Hallo toolz,

    laut meiner Man-Page erwartet pthread vier Argumente:
    int pthread_create(
            pthread_t *restrict, 
            const pthread_attr_t *restrict, 
            void *(*)(void *), 
            void *restrict);

    Du hast aber nur drei, weshalb der Rücksprung aus pthread_create() wohl zum Aufruf einer falschen Adresse führt.


  • in: Problem mit modernem OpenGL und Windows...

    geschrieben von darkpandemic

    Hallo noxious,

    bei MinGW/GCC kannst Du die fertigen Dlls einfach wie *.o Dateien an den Linker übergeben.
    D.h. Du benötigst bei GCC die *.a Datei nicht unbedingt.
    Hier ein Beispiel:
    g++ -o example_exe.exe example_exe.o example_dll.dll

    [Quelle: http://www.mingw.org/wiki/sampleDLL]

    Edit:

    Ich habe die Sache jetzt mal durchgespielt mit freeglut und glew.
    freeglut für MinGM habe ich von hier: http://www.transmissionzero.co.uk/software/freeglut-devel/
    glew für MinGW habe ich von hier: http://julianibarz.wordpress.com/2010/05/12/glew-1-5-4-mingw32/
    Mit den beiden ist das Vorgehen dann folgendermaßen:
    1.  Neues Projekt erstellen (Console oder Win32 Gui mit Frame)
    2.  Im Projektverzeichnit (d.h. dort wo die *.cbp Datei liegt) noch die Ordner 
        'glew', 'freeglut', 'dlls' und 'libs' erstellen
    3.  Die Dateine aus 'freeglut\include\GL' in das erstellte 'freeglut' 
        Verzeichnis kopieren.
    4.  Die Datei freeglut.a aus 'freeglut\lib' in das 'libs' Verzeichnis kopieren.
    5.  Die Datei freeglut.dll aus 'freeglut\dll' in das 'dlls' Verzeichnis 
        kopieren.
    6.  Die Dateine aus 'glew\include\GL' in das erstellte 'glew' Verzeichnis 
        kopieren.
    7.  Die Datei glew32.dll.a aus 'glew\lib' in das 'libs' Verzeichnis kopieren.
    8.  Die Datei glew32.dll aus 'glew\lib' in das 'dlls' Verzeichnis kopieren.
    9.  Im Menü 'Projects->Add files recursively...' klicken, das Projektverzeichnis
        auswählen und 'Ok' klicken.
        Die Header aus dem freeglut und glew Unterordnern sollten nun im Projektbaum
    	unter Headers zu finden sein.
    10. Im Menü 'Projects->Properties' wählen und im erscheinenden Dialog im Reiter 
        'Build Targets' sowohl für Release als auch Debug den Typ auf 
        'GUI application' stellen und mit 'Ok' bestätigen.
    11. Im Menü 'Projects->Build Options' klicken und im erscheinenden Dialog sowohl
        für Release als auch Debug folgendes machen:
    12. Im Reiter 'Linker settings' folgende Zeilen zur Liste 'Link libraries' 
        hinzufügen:
          libs\freeglut.a
          libs\glew32.dll.a
          opengl32
    13. Im Reiter 'Pre/Post build steps' im Feld 'Post-build steps' folgende Zeilen 
        einfügen:
          cmd /c copy "$(PROJECT_DIR)dlls\glew32.dll" "$(TARGET_OUTPUT_DIR)"
          cmd /c copy "$(PROJECT_DIR)dlls\freeglut.dll" "$(TARGET_OUTPUT_DIR)"
    14. Mit 'Ok' bestätigen.

    In die main.cpp habe ich dann folgenden Beispielcode gepackt und es lief damit:
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "glew/glew.h"
    #include "freeglut/glut.h"
    
    GLuint program;
    GLint attribute_coord2d;
    
    int init_resources(void)
    {
      GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
    
      GLuint vs = glCreateShader(GL_VERTEX_SHADER);
      const char *vs_source =
        "#version 120\n"
        "attribute vec2 coord2d;                  "
        "void main(void) {                        "
        "  gl_Position = vec4(coord2d, 0.0, 1.0); "
        "}";
      glShaderSource(vs, 1, &vs_source, NULL);
      glCompileShader(vs);
      glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
      if (0 == compile_ok)
      {
        fprintf(stderr, "Error in vertex shader\n");
        return 0;
      }
    
      GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
      const char *fs_source =
        "#version 120           \n"
        "void main(void) {        "
        "  gl_FragColor[0] = 0.0; "
        "  gl_FragColor[1] = 0.0; "
        "  gl_FragColor[2] = 1.0; "
        "}";
      glShaderSource(fs, 1, &fs_source, NULL);
      glCompileShader(fs);
      glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok);
      if (!compile_ok) {
        fprintf(stderr, "Error in fragment shader\n");
        return 0;
      }
    
      program = glCreateProgram();
      glAttachShader(program, vs);
      glAttachShader(program, fs);
      glLinkProgram(program);
      glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
      if (!link_ok) {
        fprintf(stderr, "glLinkProgram:");
        return 0;
      }
    
      const char* attribute_name = "coord2d";
      attribute_coord2d = glGetAttribLocation(program, attribute_name);
      if (attribute_coord2d == -1) {
        fprintf(stderr, "Could not bind attribute %s\n", attribute_name);
        return 0;
      }
    
      return 1;
    }
    
    void free_resources()
    {
      glDeleteProgram(program);
    }
    
    void on_display()
    {
      /* Clear the background as white */
      glClearColor(1.0, 1.0, 1.0, 1.0);
      glClear(GL_COLOR_BUFFER_BIT);
    
      glUseProgram(program);
      glEnableVertexAttribArray(attribute_coord2d);
      GLfloat triangle_vertices[] = {
         0.0,  0.8,
        -0.8, -0.8,
         0.8, -0.8,
      };
      /* Describe our vertices array to OpenGL (it can't guess its format automatically) */
      glVertexAttribPointer(
        attribute_coord2d, // attribute
        2,                 // number of elements per vertex, here (x,y)
        GL_FLOAT,          // the type of each element
        GL_FALSE,          // take our values as-is
        0,                 // no extra data between each position
        triangle_vertices  // pointer to the C array
      );
    
      /* Push each element in buffer_vertices to the vertex shader */
      glDrawArrays(GL_TRIANGLES, 0, 3);
      glDisableVertexAttribArray(attribute_coord2d);
    
      /* Display the result */
      glutSwapBuffers();
    }
    
    int main(int argc, char* argv[])
    {
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
      glutInitWindowSize(640, 480);
      glutCreateWindow("My First Triangle");
    
      GLenum glew_status = glewInit();
      if (glew_status != GLEW_OK)
      {
        fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status));
        return EXIT_FAILURE;
      }
    
      if (1 == init_resources())
      {
        glutDisplayFunc(on_display);
        glutMainLoop();
      }
    
      free_resources();
      return EXIT_SUCCESS;
    }
  • in: pop-up fenster anzeige (unten rechts)

    geschrieben von darkpandemic

    Hallo tft-development,

    falls Du unter Windows programmierst, dann kannst Du Dir ja einfach ein Fenster ohne Rahmen erzeugen.
    D.h. in WIN32 API müsstest Du z.B. folgende Window Styles löschen:
    LONG ws;
    ws = GetWindowLongPtr(window_hwnd, GWL_STYLE);
    ws &= ~(WS_BORDER|WS_CAPTION|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME);
    SetWindowLongPtr(window_hwnd, GWL_STYLE, (LONG)ws);
    SetWindowPos(window_hwnd,	HWND_TOPMOST,	0,0,0,0,SWP_NOMOVE | SWP_NOSIZE |  WP_FRAMECHANGED);

    Das Fenster kannst Du dann ja bei der Taskbar anzeigen.
    Evtl. ist noch das WS_EX_TOPMOST Flag interessant, da Du damit das Fenster in der Vordergrung bekommst.
    Vielleicht kannst Du es aber auch mit Tray-Icon und Balloon machen.

  • in: Problem mit modernem OpenGL und Windows...

    geschrieben von darkpandemic

    Hallo noxious,

    von glew kann man sich auch bereits kompilierte Binaries runterladen:
    http://glew.sourceforge.net/
    Gleich im grauen Kasten in der Mitte ("Binaries Windows 32-bit and 64-bit").
    Eine ausführliche Anleitung findest Du hier:
    http://surflab.cise.ufl.edu/wiki/Getting_Started_with_OpenGL_in_VisualC%2B%2B_2010
  • in: Index ist nicht im Arraybereich

    geschrieben von darkpandemic

    Hallo rapgru,

    wahrscheinlich ist Dein Array kleiner als Du denkst.
    Versuche mal folgendes:
    for(counterEintragen = 0; counterEintragen < result.Length; counterEintragen++)
    {
      FileInfo file = null;
      try
      {
        file = new System.IO.FileInfo(result[counterEintragen]);
      }
      catch(Exception ee)
      {
        MessageBox.Show("FEHLER " + ee.Message);
      }
      dataGridView1.Rows.Add(result[counterEintragen], "in Arbeit", file.Length + " Bytes");
    }
  • in: csv-Datei durchsuchen

    geschrieben von darkpandemic

    Hallo tft-development,

    das sollte eigentlich funktionieren:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char ** argv)
    {
      fstream csv("test.csv", fstream::in); // Öffne die Datei zum Lesen
    
      while(!csv.eof()) // Solange Dateiende nicht erreicht
      {
        string s;		
    
        getline(csv, s); // Lese Zeile	
        cout << s << endl;
      }
    	
      csv.close(); // Schließe Datei.
      return 0;
    }
    Das läuft bei mir zumindest einwandfrei. Mit Zerlegung der Zeile sieht es dann z.B. so aus:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    vector<string> * split_line(const string& line, const string& separator)
    {
      size_t start, end; // Start und Ende eines gefundenen Substrings
      size_t sep_length = separator.length(); // Länge des Separators
      vector<string> * v = new vector<string>(); // vector zum Speichern der Felder
      
      start = 0;
      
      while((end = line.find(separator, start)) != string::npos)
      {
        v->push_back(line.substr(start, end-start));
        start = end + sep_length;
      }
      
      end = line.length();
      v->push_back(line.substr(start, end-start));
    
      return v;
    }
    
    int main(int argc, char ** argv)
    {
      fstream csv("test.csv", fstream::in); // Öffne die Datei zum Lesen
      
      while(!csv.eof()) // Solange Dateiende nicht erreicht
      {
        string s;
        
        getline(csv, s); // Lese Zeile
    
        vector<string> * fields = split_line(s, "\t"); // Zerlege Zeile
        
        for(size_t i = 0; i<fields->size(); i++)
          cout << (*fields)[i] << "#"; // gebe Felder aus
          
        cout << endl;
        
        delete fields; // Zerstöre vector
    
      }
      
      csv.close(); // Schließe Datei.
      return 0;
    }

  • in: Geometrieaufgabe

    geschrieben von darkpandemic

    Hallo jocko,

    ich tippe jetzt mal auf
    Formel: \mu = 90^\circ-\frac{\alpha}{2}
    Der Weg dorthin ist wie folgt:
    http://abload.de/img/geometrie2yuvg.png
    Weil die beiden Schenkel von a Tangenten am Kreis sind stehen die Verbindungsstrecken zwischen Z und diesen Schenkeln senkrecht (Lot).
    Die Verbindungsstrecke zwischen Z und der zu m gehörigen Tangente ist ebenfalls ein Lot.
    Die Verbindungsstrecken zwischen Z und den Tangentenschnittpunkten (gestrichelte Linien) wiederum halbieren die allgemeinen Vierecke, die dadurch in je zwei spiegelsymetrische, rechtwinklige Dreiecke zerfallen.
    Jetzt kann man mit der Winkelsumme im Viereck rechnen:
    Formel: 360^\circ - 2 \cdot 90^\circ - \text{a} = 2 \cdot \left( \text{b} + \text{g} \right)
    Es gilt aber
    Formel: \text{b} + \text{g} = \text{m}
    weshalb obiges Ergebnis folgt.

  • in: Doppelverkettetes Array Plätze tauschen

    geschrieben von darkpandemic

    ggamee schrieb:
    Du hast leider total verfehlt, was ich wollte :-S aber erstmal:
    hackyourlife schrieb:
    1) NIE eine .cpp per include einbinden!

    Doch. Das muss sogar so sein. Binde ich nicht die cpp ein kann nicht mit den Templates gearbeitet werden. Probiers aus ;-)

    So leid es mit tut das sagen zu müssen, aber hackyourlife hat recht. Wenn Du die cpp-Datei inkludieren musst, dann hast Du Mist gebaut. Templates implementiert man nämlich in Header-Files wenn sie in mehr als einem Modul verwendet werden sollen.
    Daher gibt es in C++ ja Header und Module, damit man das auseinander halten kann.
  • in: Eclipse selbes Projekt Cpp(funk. nicht) vs C(funktioniert)

    geschrieben von darkpandemic

    Hallo dikay,

    Du musst den Header korrekt aufbauen:
    #ifndef _INC_LIBMEASURE_
    #define _INC_LIBMEASURE_
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    #if BUILDING_DLL
    # define DLLIMPORT __stdcall __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __stdcall __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
    
    #define BUFFSIZE 64
    
    #define RET_OK    0 /* Fehlerfreier Aufruf */
    #define RET_WINI  1 /* WinSock Initialisierung fehlgeschlagen */
    #define RET_SOCK  2 /* Fehler bei Anlage des Sockets */
    #define RET_SERV  3 /* Server nicht gefunden */
    #define RET_CONR  4 /* Verbindung vom Server abgelehnt */
    #define RET_IOF   5 /* I/O-Fehler beim Senden oder Empfangen */
    #define RET_CINV  6 /* command ungültig */
    #define RET_TIME  7 /* Timeout */
    
    DLLIMPORT
       int readMeasure(
          const char* server,
          int port,
          int timeout,
          int command,
          char* buff);
    
    DLLIMPORT
       double PCMeasureGet(
          const char* server,
          const char* name);
    
    DLLIMPORT
       int PCMeasureStatus();
    
    DLLIMPORT
       double TestDouble();
    
    DLLIMPORT
       float TestFloat();
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* _DLL_H_ */
    Die Lib ist wahrscheinlich mit C geschrieben bzw. verwendet die C Namenskonvention. In CPP werden aber die Argumente und der Rückgabewert in den Funktionsnamen mit eingebaut (-> _imp___Z12PCMeasureGetPKcS0_@8) um Überladungen zu ermöglichen weshalb der Linker die C-Funktionen nicht finden kann. Daher sollte man immer CPP-Guards im Header haben, wenn man eine C-Bibliothek schreibt.

  • in: Assembler: Extern sprintf

    geschrieben von darkpandemic

    Hallo toolz,

    Du musst die Gleitkommazahl als double, d.h. 64-Bit / 8-Byte Zahl, übergeben. Dann sollte es funktionieren.
  • in: Möglichkeit Double-Werte zu kürzen

    geschrieben von darkpandemic

    Hallo yorecords,

    ich verstehe zwar, was Du gerne hättest aber ich befürchte, dass das im Allgemeinen nicht funktioniert.
    Der Grund ist der Folgende:
    Du willst eine Menge von Zahlen auf eine andere Menge von Zahlen abbilden und zwar mit Hilfe einer bijektiven Abbildung.
    D.h. die Funktion muss für zwei verschiedene Zahlen immer auch zwei verschiedene Werte zurückliefern und sie muss auch noch invertierbar sein.
    Desweiteren sollen die Zahlen in Textdarstellung möglichst kurz sein.
    Wenn Du keine Lücken in Deiner Ausgangsmenge hast, d.h. jede Zahl zwischen -999999999.99999999999 und 999999999.99999999999 auch auftreten kann, dann sind alle kurzen Zahlen bereits mit sich selbst belegt, weshalb die Identität bereits die beste Abbildung ist, die Deine Anforderungen erfüllt.
    Wenn Du aber Lücken hast, d.h. Du z.B. weist, dass Zahlen zwischen 1000 und 10000 nicht auftreten, dann könnte man 9000 größere Werte auf diesen freien Bereich abbilden:
    100000 -> 1000
    100001 -> 1001
    ...
    109999 -> 9999
    110000 -> 10000

    Wenn Du keine Lücken hast, dann kannst Du evtl. noch mit Statistik was machen. Wenn Deine Zahlen nicht gleichmäßig verteilt sind, d.h. mit unterschiedlich hohen Wahrscheinlichkeiten auftreten, dann kannst Du Zahlen mit hoher Wahrscheinlichkeit auf niederwertige Ganzzahlen abbilden und die frei werdenden höherwertigen (längeren) Zahlen mit weniger wahrscheinlichen Werten assoziieren.
    Damit ließe sich dann auch etwas Platz sparen. Allerdings benötigst Du dafür entweder eine geschickt gebaute Funktion die sich aus der Wahrscheinlichkeitsdichte ableitet oder eine riesen Look-Up-Table.
  • in: Array während While füllen

    geschrieben von darkpandemic

    Hallo hc-tools,

    Arrays (eigentlich meinst Du Listen, oder?) sind für Dein Vorhaben der falsche Datentyp.
    Die IDs in der Datenbank müssen ja nicht konsekutiv sein, d.h. es können Zahlen fehlen, weshalb Du evtl. sogar leere Elemente einfügen müsstest.
    Was Du verwenden musst sind Dictionaries:
    import mysql.connector
    
    config = {
      'user': 'root',
      'password': '',
      'host': '127.0.0.1',
      'database': 'carrera_auto',
      'raise_on_warnings': True,
    }
    
    cnx = mysql.connector.connect(**config)
    cursor = cnx.cursor('i')
    query = ("SELECT id, speed, flag FROM speed")
    cursor.execute(query)
    
    results = {}
    for (id, speed, flag) in cursor:
        results[id] = {'speed' : str(speed), 'flag' : str(flag)}
    
    cursor.close()
    cnx.close()
    
    print(results)
  • in: DirectX-Programmierung

    geschrieben von darkpandemic

    Hallo fockolino,

    auf der Webseite zum Buch scheint es ja einen Download-Bereich zu geben, in dem man sich die Programmbeispiele herunterladen kann.
    Das SDK kannst Du Dir direkt bei Microsoft herunterladen:
    http://www.microsoft.com/en-us/download/details.aspx?id=6812
    Und wenn Du ein Visual Studio benötigst, dann bekommst Du es mit einem kostenlosen Windows-Live Account hier:
    http://www.microsoft.com/visualstudio/deu/downloads#d-2010-express
  • in: Was ist so toll an Eclipse?

    geschrieben von darkpandemic

    Hallo fatfox,

    KTechlab sieht eigentlich ganz interessant aus. Aber soweit ich das sehe ist das für PIC-Controller.
    Die berüchtigte Bienenmessstation wird aber mit einem Freescale µC betrieben. Nachdem ich aber nur mein Arduino habe, was ja ein Atmel ist, benötige ich halt einen Simulator für den Freescale µC um zumindest ein paar Code-Fragmente mal testen zu können.
    Und den bekommt man halt nur bei Freescale als bestandteil der CodeWarrior IDE. Aber nachdem der Debugger in der Eclipse-Variante nach ein paar hopsern den Dienst versagt landet es halt wieder im Müll und ich teste in der VM mit der älteren Version.

    Edit: Und ich muss zustimmen, Geany gehört auch zu den guten Werkzeugen. Es ist einfach und übersichtlich und erfüllt seinen Zweck ;-)
  • in: Was ist so toll an Eclipse?

    geschrieben von darkpandemic

    Hallo alle miteinander,

    nachdem Eclipse eine scheinbar sehr verbreitete und beliebte IDE ist gebe ich ihr alle paar Jahre mal eine Chance mich zu überzeugen.
    Heute hätte sie wieder eine Chance gehabt. Da die alte CodeWarrior IDE für Mikrocontroller unter Win7 64 Bit nicht läuft und ich mir das arbeiten in der VM sparen wollte habe ich mir die neuere Version besorgt, welche auf Eclipse basiert.
    Und nach nicht mal einer Stunde rumspielen damit bin ich wieder zum selben Ergebnis gelangt wie die vielen male zuvor:

    Unintuitive bzw. schlecht organisierte UI, schlechte Konfigurationsmöglichkeiten und wegen Bugs produktiv nicht zu gebrauchen.

    Ich habe ja mittlerweilen schon mit vielen IDEs (auch simplen Editoren) programmiert, wie z.B. vi, PSPad, UltraEdit, JEdit, IDLE, PyScripter, Anjuta, KDevelop, DevC++, Code::Blocks, Netbeans, Visual Studio...
    Mit all diesen Sachen kann man meiner Meinung nach hervorragend arbeiten. Aber Eclipse empfinde ich als Katastrophe.
    Daher will ich jetzt mal Meinungen hören, was an Eclipse so gut ist? Warum können sich Leute ernsthaft für diese IDE begeistern?

    Grüße
    darkpandemic


  • in: Programmierproblem Assembler

    geschrieben von darkpandemic

    Die Sache scheint ja so zu laufen:
    Du schickst ein Kommando über die serielle Schnittstelle an das GSM-Modul und das GSM-Modul sendet Dir dann eine Antwort zurück.
    Du schreibst z.B. 'AT' auf die serielle Schnittstelle und das GSM-Modul sollte dann 'OK' zurückschicken.
    Oder zum Abfragen der Softare-Version schreibst Du 'AT+CGMR' und bekommst z.B '10.00.004' und dann noch ein 'OK'.
    Allerdings sieht man in der Dokumentation erstmal nicht, ob Zeilenumbrüche die einzelnen Blöcke trenne.
    Auf jedenfall musst Du Dir die Antwort immer anschauen, anstelle von 'OK' kann ja auch ein 'ERROR' oder '+CDE ERROR: ...' usw. zurückkommen. Also wirst Du wohl ein paar Funktionen benötigen um das alles zu verarbeiten.
  • in: Programmierproblem Assembler

    geschrieben von darkpandemic

    Hallo seppelin,

    im Datenblatt zum µC ist wohl Kapitel 11 interessant.
    Allerdings musst Du wohl noch was dazwischen schalten, da Dein µC vermutlich mit 5V-Pegeln und das GSM-Modul mit 2.8V-3V Pegeln arbeitet.
    Dazu steht hier was im Abschnitt 9.3.
    Auf jeden Fall darfst Du Dir jetzt ein paar String-Funktionen in Assembler schreiben.
  • in: Elektrotechnik für Kurzentschlossene

    geschrieben von darkpandemic

    Ja, das ist jetzt noch ein schöner Abschluss für den Tag :megarofl:
    Ich wünsche jetzt eine gute Nacht :sleep:
  • in: Programmierproblem Assembler

    geschrieben von darkpandemic

    Naja, wenn Dein Lehrer den Fehler auch nicht sieht, dann fühle ich mich gleich besser :prost:
  • in: Elektrotechnik für Kurzentschlossene

    geschrieben von darkpandemic

    Nachdem der Thread im Spam-Forum ist, hätte ich eigentlich 'Elektrotechnik für Kuzgeschlossene' erwartet ;-)
  • in: Programmierproblem Assembler

    geschrieben von darkpandemic

    Hallo seppelin,

    freut mich, dass es mit 2 LUTs funktioniert (spart Dir die 16-Bit Addition).
    Aber rein aus Neugirde, hast Du es auch mit umgekehrter Reihenfolge der Bytes beim Addieren versucht?
    Also zwei mal:
    lda     1, X                    ; Lade LUT_POINTR[1] -> A
    add     ADC_Wert_PB0            ; Addiere PB0 zu A
    sta     1, X                    ; Speichere A -> LUT_POINTER[1]
    lda     0, X                    ; Lade LUT_POINTER[0] -> A
    adc     #0                      ; Addiere Überhang
    sta     0, X                    ; Speichere A -> LUT_POINTER[0]

    Und weil mir das Rumraten gerade solchen Spaß macht, noch ein (vielleicht mieser) Vorschlag:
    lda     ADC_Wert_PB0    ; Lade ADC-Wert -> A
    cmp     #43             ; Vergleiche mit 43
    blo     ADD_SIGN        ; Wenn kleiner springe zu ADD_SIGN
    <normale Ausgabe>       ; sonst normale Ausgabe


  • in: Programmierproblem Assembler

    geschrieben von darkpandemic

    Hallo seppelin,

    zuerst zur Frage, warum man den ADC-Wert mit Zwei multiplizieren muss:
    Dazu muss man sich anschauen, wie Deine Wertetabelle im Speicher abgelegt ist.
    Der Ausdruck dc.b sagt dem Assembler, dass er es hier mit Byte-Werten zu tun bekommt. Danach kannst Du entweder eine einzelne Zahl oder eine durch Kommas getrennte Liste von Zahlen angeben, welche im Speicher der Reihe nach als 1-Byte große Werte abgelegt werden. Wenn danach eine neue Zeile mit einem weiteren dc.b kommt, dann werden diese Werte einfach dahinter abgelegt. Die ersten fünf Einträge Deiner Lookup-Table erzeugen daher folgende Byte-Reihenfolge im Speicher:
    +------+---+---+---+---+---+---+---+---+---+---+
    |Offset|  0|  1|  2|  3|  4|  5|  6|  7|  8|  9|
    +------+---+---+---+---+---+---+---+---+---+---+
    |Wert  | 10|  0|  9|  9|  9|  8|  9|  7|  9|  6|
    +------+---+---+---+---+---+---+---+---+---+---+
    |Type  |  G|  N|  G|  N|  G|  N|  G|  N|  G|  N|
    +------+---+---+---+---+---+---+---+---+---+---+
           ^
           |
           Basisadresse = #Ausgabe_Temp_Muster
    Hierbei ist steht unter Offset der Abstand zur Basisadresse, unter Wert der Wert des Bytes an der Adresse <Basisadresse> + <Offset> und Type gibt an, ob es sich um den Ganzzahlanteil (G) oder den Nachkommaanteil (N) handelt.
    Wenn der ADC-Wert z.B. 3 ist, dann willst Du als Ausgabe ja den Wert 9.7 erzeugen. Wenn Du jetzt in obige Tabelle schaust, dann siehst Du, dass der zugehörige Ganzzahlanteil bei Offset 6 und der Nachkommastellenanteil bei Offset 7 zu finden ist, weil ja jedes Zahlenpaar 2 Byte im Speicher belegt.
    Daher gilt:
    <Adresse Ganzzahlanteil> = <Basisadresse> + 2 * <ADC-Wert>
    und
    <Adresse Nachkommastelle> = <Basisadresse> + 2 * <ADC-Wert> + 1

    Und jetzt zurück zum Code:
    Ich habe noch ein bisschen herumgesucht und dabei hat sich mein ungutes Gefühl bestätigt :scared:
    Man muss hier wohl Syntaktisch sehr aufpassen, wann man es mit einer Adresse und wann mit dem eigentlichen Wert zu tun hat.
    Soweit ich es verstanden habe würde z.B. folgendes:
    ldhx    Ausgabe_Temp_Muster
    die ersten beiden Bytes aus der Lookup-Table in das Registerpaar H:X laden. Um die Basisadresse zu laden hätte man
    ldhx    #Ausgabe_Temp_Muster
    schreiben müssen. Also war die erste Zeile schon einmal Quatsch.
    Die Idee wäre ja gewesen die Basisadresse nach H:X zu laden und dann den 8-Bit ADC-Wert dazu zu addieren. Die Zeile
    lda 0, X
    lädt aber nicht das X-Register in den Akkumulator sondern das Byte, das im Speicher an der Position H:X+0 steht. Also nicht das was man eigentlich will. Im Datasheet habe ich gesehen, dass es die Befehle tax und txa gibt mit denen man zumindest das X-Register in den Akkumulator kopieren und den Akkumulator wieder in das X-Register befördern kann. Leider gibt es sowas für das H-Register nicht. Also wenn man sowas wie
    mov A, H
    bzw.
    mov H, A
    nicht schreiben kann, dann führt der Weg über das H:X Register nicht zum Ziel und man muss stattdessen über den Speicher gehen.
    Also der nächste Versuch, der vielleicht nicht mehr ganz so falsch ist:
    Variable für die berechnete Adresse:
    LUT_POINTER
    	ds.w 1
    Der (vielleicht etwas richtigere) Code:
    ldhx    #Ausgabe_Temp_Muster    ; Lade Basisadresse -> H:X
    sthx    LUT_POINTER             ; Speichere Basisadresse -> LUT_POINTER
    ldhx    #LUT_POINTER            ; Lade Adresse von LUT_POINTER -> H:X
    
    ; 1. Addition:
    lda     0, X                    ; Lade LUT_POINTR[0] -> A
    add     ADC_Wert_PB0            ; Addiere PB0 zu A
    sta     0, X                    ; Speichere A -> LUT_POINTER[0]
    lda     1, X                    ; Lade LUT_POINTER[1] -> A
    adc     #0                      ; Addiere Überhang
    sta     1, X                    ; Speichere A -> LUT_POINTER[1]
    
    ; 2. Addition:
    lda     0, X                    ; Lade LUT_POINTR[0] -> A
    add     ADC_Wert_PB0            ; Addiere PB0 zu A
    sta     0, X                    ; Speichere A -> LUT_POINTER[0]
    lda     1, X                    ; Lade LUT_POINTER[1] -> A
    adc     #0                      ; Addiere Überhang
    sta     1, X                    ; Speichere A -> LUT_POINTER[1]
    
    ldhx    LUT_POINTER             ; Lade berechnete Adresse -> H:X
    lda     0, X                    ; Ganzzahlanteil -> A
    lda     1, X                    ; Nachkommaanteil -> A
    Hierbei wurde wieder angenommen, dass die Adresse Little-Endian ist. Ansonsten muss beim Addieren erst das erste und danach das nullte Byte geladen werden.

    Edit: Variablendeklaration korrigiert.
  • in: Programmierproblem Assembler

    geschrieben von darkpandemic

    Hallo seppelin,

    dann ist es eher Lösungsansatz Nummer 2. Allerdings hat eine Speicherstelle bei Dir 2 Byte, weshalb man den ADC Wert mit 2 Multiplizieren müsste. Also gilt:
    <Adresse des Zahlenpaares> = <Basisadresse> + 2 * <ADC Wert>
    Nachdem die Multiplikation das X Register verwendet, in welchem wir die Basisaddresse haben, und der Akkumulator nur 8-Bit groß ist schreiben wir das lieber zu:
    <Adresse des Zahlenpaares> = <Basisadresse> + <ADC Wert> + <ADC Wert>
    um ;-)
    Könnte dann in etwa so aussehen:
    ldhx    Ausgabe_Temp_Muster     ; Lade Basisadresse -> H:X
    
    ; 1. Addition:
    lda     0, X                    ; Lade H:X[0] -> A
    add     ADC_Wert_PB0            ; Addiere PB0 zu A
    sta     0, X                    ; Speichere A -> H:X[0]
    lda     1, X                    ; Lade H:X[1] -> A
    adc     #0T                     ; Addiere Überhang
    sta     1, X                    ; Speichere A -> H:X[1]
    
    ; 2. Addition:
    lda     0, X                    ; Lade H:X[0] -> A
    add     ADC_Wert_PB0            ; Addiere PB0 zu A
    sta     0, X                    ; Speichere A -> H:X[0]
    lda     1, X                    ; Lade H:X[1] -> A
    adc     #0T                     ; Addiere Überhang
    sta     1, X                    ; Speichere A -> H:X[1]
    
    sthx    Pointer_Temp            ; Speichere H:X -> (Pointer_Temp:Pointer_Temp+1)
    Allerdings bin ich mir jetzt nicht ganz sicher, ob ich die Befehle ldhx, sthx und vor allem das lda *, X bzw. sta *,X richtig interpretiere. Aber ich hoffe die Grundidee ist klar.

    Edit: Falsch kopiert.

  • in: Programmierproblem Assembler

    geschrieben von darkpandemic

    Hallo seppelin,

    so ganz verstehe ich den Code noch nicht. Ich würde als naheliegenstes mal fogendes versuchen:
    ldhx    Pointer_Temp    ; Lade (Pointer_Temp:Pointer_Temp+1) -> H:X
    lda     0, X            ; Lade H:X[0] -> A
    add     ADC_Wert_PB0    ; Addiere PB0 zu A
    sta     0, X            ; Speichere A -> H:X[0]
    lda     1, X            ; Lade H:X[1] -> A
    add     ADC_Wert_PB0    ; Addiere PB0 zu A
    sta     1, X            ; Speichere A -> H:X[1]
    sthx    Pointer_Temp    ; Speichere H:X -> (Pointer_Temp:Pointer_Temp+1)
    Allerdings kenne ich jetzt die MCU nicht und das Datenblatt ist auch nicht sehr ausführlich, was die Befehle angeht. Ich bin davon Ausgegangen, dass Pointer_Temp ein Lable bzw. eine Adresse darstellt und ADC_Wert_PB0 ein 8-Bit Wert ist. Nachdem ich jetzt aber nicht weis, wie deine Lookup-Table aussieht erschließt sich mir nicht, inwiefern das Addieren des ADC-High-Bytes sowohl zum niederwertigen als auch zum höherwertigen Byte ein sinnvolles Ergebnis liefern soll. Ich vermute jetzt einfach mal, das Du eigentlich eher eine Addition mit Übertrag (with Carry) benötigst um den Zeiger auf die Lookup-Table korrekt zu erhöhen.
    Desweiteren sieht es so aus, als ob Du ständig den Zeiger erhöhst, d.h. Du summierst die ADC-Werte immer weiter auf, was eigentlich irgenwann zu einem Überlauf führen müsste.
    Ich vermute weiter, dass Du eigentlich sowas haben willst:
    <Zeiger auf Text> = <Basisadresse>+<ADC-Wert>
    Dann könnte es vielleicht so aussehen:
    ldhx    lookup_base     ; Lade Basisadresse der LUT -> H:X
    lda     0, X            ; Lade H:X[0] -> A
    add     ADC_Wert_PB0    ; Addiere PB0 zu A
    sta     0, X            ; Speichere A -> H:X[0]
    lda     1, X            ; Lade H:X[1]
    adc     #0T             ; Addiere Übertrag zu A
    sta     1, X            ; Speichere A -> H:X[1]
    sthx    text_address    ; Speichere H:X -> Text Adresse
    Das ist jetzt unter der Annahme, dass lda 0,X das niederwertige Byte lädt, ansonsten musst Du erst lda 1,X und als zweites lda 0,X schreiben. Desweiteren darf das Carry-Flag durch die Lade und Speicher Befehle nicht geändert werden, sonst funktioniert es nicht.


  • in: Visual Basic Fenster vergößern

    geschrieben von darkpandemic

    Hallo skateen,

    das Umstellen mit dem Code ist ja nur eine Alternative. Das kannst Du z.B. direkt in den Load-Handler einfügen:
    Public Class Form1
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
            Me.WindowState = FormWindowState.Maximized
            WebBrowser1.Navigate("http://URL")
        End Sub
    
        Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
    
        End Sub
    End Class
    Aber wenn Dein Programm immer im Fullscreen-Modus und nie im normalen Fenster-Modus laufen soll, dann kannst Du es, wie oben Beschrieben, einfach in der Entwurfsansicht in den Eigenschaften des Fensters festlegen (gleiches Fenster wie bei der Dock-Eigenschaft) und benötigst den Code nicht.
  • in: Visual Basic Fenster vergößern

    geschrieben von darkpandemic

    Hallo skateen,

    die Programmiersprache heißt Visual Basic und nicht Virtuell Basic.
    Zu Deinen Fragen:
    Damit das Browser-Control sich an die Größe Deines Fensters anpasst musst Du es in der Entwurfsansicht so groß mache, dass es das gesamte Fenster ausfüllt und dann die Dock-Eigenschaft auf Fill setzen.
    Das sollte dann so aussehen:
    http://www.abload.de/img/vb_browser_fill4eucl.png
    Um Dein Fenster Fullscreen zu machen musst Du in der Entwurfsansicht das Fenster (die Form) auswählen und in den Eigenschaften FormBorderStyle auf None einstellen und WindowState auf Maximized.
    Wenn Du es per Code machen willst, dann sieht das folgendermaße aus:
    Fullscreen:
    Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
    Me.WindowState = FormWindowState.Maximized
    Fullscreen beenden:
    Me.WindowState = FormWindowState.Normal
    Me.FormBorderStyle = Windows.Forms.FormBorderStyle.Sizable
    Wenn Du Deine Nutzer noch ärgern willst, dann setzt Du im Fullscreen-Mode noch die TopMost-Eigenschaft auf True ;-)
  • in: Absolut Top Secret!

    geschrieben von darkpandemic

    Also ich finde die Seite klasse.
    Da werden Erinnerungen and die 90er des letzten Jahrhunderts wach.
    :thumb:
  • in: C++ Text zu Bitmap

    geschrieben von darkpandemic

    Hallo mator-kaleen,

    erstmal eine kleine Korrektur:
    Das erzeugte Bild liegt im Bottom-Up- und nicht im Top-Down-Fromat vor. D.h. die erste Datenzeile entspricht der untersten Bildzeile und nicht der obersten. Daher müssen die getPixel()- und setPixel()-Methoden leicht modifiziert werden um das übliche Verhalten zu bekommen:
    COLORREF getPixel(int x, int y)
    {
      if(x < 0 || x >= this->width)
      {
        throw new std::invalid_argument("x value out of bounds.");
      }
    
      if(y < 0 || y >= this->height)
      {
        throw new std::invalid_argument("y value out of bounds.");
      }
    
      // invert y coordinate
      y = this->height-1-y;
    
      return RGB(this->data[y][3*x+2],this->data[y][3*x+1],this->data[y][3*x]);
    }
    
    void setPixel(int x, int y, COLORREF color)
    {
      if(x < 0 || x >= this->width)
      {
        throw new std::invalid_argument("x value out of bounds.");
      }
    
      if(y < 0 || y >= this->height)
      {
        throw new std::invalid_argument("y value out of bounds.");
      }
    
      // invert y coordinate
      y = this->height-1-y;
    
      this->data[y][3*x] = GetBValue(color);
      this->data[y][3*x+1] = GetGValue(color);
      this->data[y][3*x+2] = GetRValue(color);
    }
    Mit OpenGL wirst Du nicht weiter kommen, da OpenGL von sich aus kein Font-Rendering unterstützt. Um Text mit OpenGL anzuzeigen muss man auch erst den Text in eine Bitmap bzw. Textur zeichnen und diese dann in die Graphikkarte übertragen.
    Allerdings kannst Du obigen Code natürlich für diese Vorstufe verwenden.
    Wenn man unter Linux Text rendern will, dann kann man es einerseits auf die harte Tour machen indem man die FreeType Library verwendet. Das ist der absolute Low-Level Ansatz und sich das anzutun ist wohl sehr lehrreich aber in der Praxis wird man es eher nicht damit machen.
    In der Dokumentation dazu sind auch Tutorials bei denen man sich anschauen kann, wie so etwas aussieht.
    Unter Linux ist es vernünftiger die Graphikfunktionen eines Toolkits zu verwenden. Für C++ kann man da z.B. QT oder wxWidgets verwenden. Dabei hat man sogar den Vorteil, dass es nicht nur unter Linux sondern auch unter Windows läuft.
    Unter QT wäre die QPainter-Klasse das Analogon zum Device Context und QImage kann man als Bild verwenden. Bei wxWidgets gibt es die wxDC-Klasse als normalen Device Context und die wxMemoryDC-Klasse um in Bilder (wxBitmap) zu zeichnen.
    Ich persönlich fand wxWidgets einfacher zu handhaben weshalb ich es jetzt einfach mal für den Anfang empfehle.
    In QT sind mittlerweile schon so viele andere Techniken drin, dass man sich als Anfänger unter Umständen nur schwer zurechtfindet.
  • in: C++ Text zu Bitmap

    geschrieben von darkpandemic

    Hallo mator-kaleen,

    mit GDI bzw. GDI+ liegst Du eigentlich richtig. Du musst Dein Bild (Bitmap-Array) nur mit Hilfe von CreateDIBSection() erzeugen.
    #include <Windows.h>
    #include <iostream>
    #include <fstream>
    
    class BMPImage
    {
      private:
    
      int width;
      int height;
      unsigned char ** data;
      HBITMAP hbm;
    
    
      public:
    
      BMPImage(int width, int height)
      {
        int i, line_size;
        BITMAPINFO bih = {0};
        HDC hdc;
    
        if(width<1 || height<1)
        {
          throw new std::invalid_argument("Invalid image size.");
        }
    
        this->width = width;
        this->height = height;
    
        try
        {
          this->data = new unsigned char*[height];
        }
        catch(std::bad_alloc&)
        {
          throw new std::bad_alloc("Allocation for image rows failed.");
        }
    
        bih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bih.bmiHeader.biWidth = width;
        bih.bmiHeader.biHeight = height;
        bih.bmiHeader.biPlanes = 1;
        bih.bmiHeader.biBitCount = 24;
        bih.bmiHeader.biCompression = BI_RGB;
    
        hdc = CreateCompatibleDC(0);
        this->hbm = CreateDIBSection(hdc,&bih,DIB_RGB_COLORS,(void**)&this->data[0],0,0);
        DeleteDC(hdc);
    
        if(!this->hbm)
        {
          delete[] this->data;
          throw new std::bad_alloc("Allocation of DIB section failed.");
        }
    
        if((width)%4)
          line_size = 3 * width + (4 - (width * 3) % 4);
        else
          line_size = 3 * width;
    
        for(i=1;i<height;i++)
          this->data[i]= &this->data[0][line_size*i];
      }
    
      ~BMPImage()
      {
        DeleteObject(this->hbm);
        delete[] this->data;
      }
      
      int getWidth() { return this->width;}
      int getHeight() { return this->height;}
      HBITMAP getHandle() { return this->hbm; }
    
      COLORREF getPixel(int x, int y)
      {
        if(x < 0 || x >= this->width)
        {
          throw new std::invalid_argument("x value out of bounds.");
        }
    
        if(y < 0 || y >= this->height)
        {
          throw new std::invalid_argument("y value out of bounds.");
        }
    
        return RGB(this->data[y][3*x+2],this->data[y][3*x+1],this->data[y][3*x]);
      }
    
      void setPixel(int x, int y, COLORREF color)
      {
        if(x < 0 || x >= this->width)
        {
          throw new std::invalid_argument("x value out of bounds.");
        }
    
        if(y < 0 || y >= this->height)
        {
          throw new std::invalid_argument("y value out of bounds.");
        }
    
        this->data[y][3*x] = GetBValue(color);
        this->data[y][3*x+1] = GetGValue(color);
        this->data[y][3*x+2] = GetRValue(color);
      }
    
      bool save(const char * filename)
      {
        std::ofstream * fout;
        BITMAPFILEHEADER bfh = {0};
        BITMAPINFOHEADER bih = {0};
        RGBQUAD rgbq = {0};
        int line_size;
    
        if(!filename)
        {
          throw new std::invalid_argument("filename is null.");
        }
    
        if((this->width)%4)
          line_size = 3* this->width + (4 - (this->width * 3) % 4);
        else
          line_size = 3 * this->width;
    
        bfh.bfType = MAKEWORD('B', 'M');
        bfh.bfSize =  sizeof(BITMAPFILEHEADER)
              + sizeof(BITMAPINFOHEADER)
              + sizeof(RGBQUAD)
              + this->height * line_size;
        bfh.bfReserved1=0;
        bfh.bfReserved2=0;
        bfh.bfOffBits =    sizeof(BITMAPFILEHEADER)
                + sizeof(BITMAPINFOHEADER)
                + sizeof(RGBQUAD);
    
        bih.biSize = sizeof(BITMAPINFOHEADER);
        bih.biWidth = this->width;
        bih.biHeight = this->height;
        bih.biPlanes = 1;
        bih.biBitCount = 24;
        bih.biCompression = BI_RGB;
    
        fout = new std::ofstream(filename, std::ios::out|std::ios::binary);
        if(fout->fail())
        {
          delete fout;
          return false;
        }
    
        fout->write((const char *)&bfh,sizeof(BITMAPFILEHEADER));
        fout->write((const char *)&bih,sizeof(BITMAPINFOHEADER));
        fout->write((const char *)&rgbq, sizeof(RGBQUAD));
        fout->write((const char *)this->data[0],line_size*this->height);
    
        if(fout->fail() || fout->bad())
        {
          fout->close();
          return false;
        }
        else
        {
          fout->close();
          return true;
        }
      }
    };
    
    HFONT getFont(const char * name, int size, bool italic = false, bool bold = false, bool underline = false, bool strike_out = false)
    {
      LOGFONT lfont = {0};
    
      lfont.lfQuality = CLEARTYPE_QUALITY;
      lfont.lfCharSet = DEFAULT_CHARSET;
    
      strncpy(lfont.lfFaceName, name, 31);
      lfont.lfHeight = -size;
      if(italic) lfont.lfItalic = TRUE;
      if(bold) lfont.lfWeight= FW_BOLD;
      if(underline) lfont.lfUnderline = TRUE;
      if(strike_out) lfont.lfStrikeOut = TRUE;
    
      return CreateFontIndirect(&lfont);
    }
    
    int main(int argc, char ** argv)
    {
      // create image
      BMPImage * img = new BMPImage(256, 256);
    
      // create device context for painting
      HDC hdc = CreateCompatibleDC(NULL);
    
      // select bitmap into DC
      HBITMAP hbm_old = (HBITMAP)SelectObject(hdc, img->getHandle());
    
      // define rect for painting
      RECT rect = {0,0,img->getWidth(), img->getHeight()};
    
      // draw white background
      FillRect(hdc, &rect, WHITE_BRUSH);
    
      // create and select font
      HFONT font = getFont("Comic Sans MS", 40, false, true, true);
      HFONT font_old = (HFONT)SelectObject(hdc, font);
    
      // set text color and background mode
      SetTextColor(hdc, RGB(255, 0, 128));
      SetBkMode(hdc, TRANSPARENT);
    
      // draw centered text
      DrawText(hdc, "Hallo", -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
    
      // replace DC bitmap and font by original one
      SelectObject(hdc, font_old);
      SelectObject(hdc, hbm_old);
    
      // free font and device context
      DeleteObject(font);
      DeleteDC(hdc);
    
      // save image
      img->save("test.bmp");
    
      // clean up
      delete img;
      return 0;
    }
    Alpha-Kanal ist in dem Beispiel zwar nicht dabei. Aber zumindest kannst Du Dir hier anschauen, wie man eine Bitmap erzeugt, diese in einen Device Context lädt, Text reinmalt und am Ende alles als .bmp speichert.
  • in: variable in anderer methode

    geschrieben von darkpandemic

    Hallo nicolas-k,

    wenn Du ein Array hast, dann benötigst Du das ref-Schlüsselwort eigentlich gar nicht.
    Es gibt bezüglich der Übergabe an Methoden/Funktionen zwei Arten von Datentypen. Das sind einerseits Wert-Datentypen und andererseits Referenz-Datentypen.
    Wert-Datentypen werden als Wert (by value) übergeben. D.h. die Methode oder Funktion bekommt eine Kopie des übergebenen Wertes und Änderungen des Wertes ändern nur die Kopie nicht aber die ursprüngliche Variable.
    Wert-Datentypen sind alle elementaren Datentypen wie Ganzzahlen, Fließkommazahlen und boolsche Werte. Desweiteren werden auch Strukturen (struct) und Aufzählungen (enum) als Wert-Datentypen übergeben. Hier müsste man das ref-Schlüsselwort verwenden um eine Übergabe als Referenz zu erzwingen, was dann eine Änderung der ursprünglichen Variable möglich macht.
    Alle anderen Datentypen (class, interface, delegate, Arrays, ...) sind Referenz-Datentypen und werden von Haus aus als Referenz übergeben.
    Hier führt eine Änderung immer zur Änderung der ursprünglichen Variablen. Auch ohne dass ref angegeben wurde.

    Noch ein Hinweis zur Parallelisierung:
    Wenn Du relativ einfache Operationen parallelisieren willst, dann gibt es in System.Threading.Tasks einige nette Sachen.
    Z.B. Parallel.For was eine Schleife parallelisiert ausführt ohne, dass Du explizit mit Threads hantieren musst.
    Hier mal ein kleines Beispiel, welches ein Array mit den Quadraten des Element-Index füllt:
    using System;
    using System.Threading.Tasks;
     
    namespace testing
    {
        class Program
        {
            void getSquares(int[] arr)
            {
                // fill array with the squared index by using blocks of 10 elements:
                Parallel.For(0, (arr.Length + 9) / 10, i =>
                {
                    int idx = 10*i; // compute start index
    
                    // fill block
                    for (int j = 0; j < 10 && idx < arr.Length; j++, idx++)
                        arr[idx] = idx*idx;
                });
            }
     
            static void Main(string[] args)
            {
                int[] arr = new int[101];
    
                getSquares(arr);
    
                foreach (int i in arr)
                    Console.WriteLine(i);
            }
        }
    }
    Hierbei iteriert die Parallel.For-Schleife über Blöcke mit jeweils 10 Elementen und die innere for-Schleife füllt jeweils einen Block mit den entsprechenden Werten. Mehrere Blöcke werden hierbei parallel abgearbeitet.


  • in: schallberechnung prrogrammiersprache erst einmal egal

    geschrieben von darkpandemic

    Hallo simuliertes,

    evtl. wäre OpenAL was.
    Laut Spezifikation sollte es auch Reflexionen können.
    Allerdings habe ich damit noch nie etwas gemacht, weshalb ich nichts weiter dazu sagen kann.
  • in: variable in anderer methode

    geschrieben von darkpandemic

    Hallo nicolas-k,

    Du hast drei Möglichkeiten. Entweder Du definierst die Variable auf Klassen-Ebene oder Du übergibst sie als Referenz oder Du gibst den neuen Wert als Rückgabewert zurück.
    1. Möglichkeit:
    using System;
    
    namespace testing
    {
        class Program
        {
            private static int variable = 5;
    
            static void Main(string[] args)
            {
                Console.WriteLine(variable);
                change();
                Console.WriteLine("after calling change: " + variable);
                Console.ReadKey();
            }
    
            public static void change()
            {
                variable = 10;
            }
        }
    }
    2.Möglichkeit:
    using System;
    
    namespace testing
    {
        class Program
        {
            static void Main(string[] args)
            {
                int variable = 5;
                Console.WriteLine(variable);
                change(variable);
                Console.WriteLine("after calling change: " + variable);
                Console.ReadKey();
            }
    
            public static void change(ref int variable)
            {
                variable = 10;
            }
        }
    }
    3. Möglichkeit:
    using System;
    
    namespace testing
    {
        class Program
        {
            static void Main(string[] args)
            {
                int variable = 5;
                Console.WriteLine(variable);
                variable = change(variable);
                Console.WriteLine("after calling change: " + variable);
                Console.ReadKey();
            }
    
            public static int change(int variable)
            {
                return variable + 5;
            }
        }
    }
  • in: Tabellen verbinden - Problem

    geschrieben von darkpandemic

    Hallo fuerderer,

    du musst die WHERE-Klausel ans Ende packen:
    SELECT * FROM techniksessions
    LEFT JOIN technikzugaenge ON techniksessions.zugangsid = technikzugaenge.id
    WHERE techniksessions.sessid='0123456789abcdef0123456789abcdef'

  • in: Seil "Kapper"

    geschrieben von darkpandemic

    Hallo christian1603,

    an sowas wie diesen "Hochstarthaken" vom fatfreddy hätte ich auch gedacht. Ich wusste nur nicht dass es sowas fertig gibt geschweige denn, wie sowas heißt.
    Mir ist noch ein Gedanke dazu gekommen: Zum auslösen des Haken könnte man evtl. einen Hubmagneten verwenden. Die sind ungefähr genau so schwer wie ein Servo benötigen kein PWM, d.h. es reicht ein Port um ihn auszulösen, und verbrauchen im verriegelten Zustand keinen Strom da sie durch eine Rückstellfeder in Position gehalten werden.
    Allerdings sind diese nicht besonders kräftig, weshalb ich nicht sagen kann ob das unter der angegebenen Last zuverlässig funktioniert.
  • in: scanline-algorithmus

    geschrieben von darkpandemic

    Hallo nicolas-k,

    ich konnte jetzt keine ungewöhnliches Verhalten feststellen.
    Du hast 3 Eingabezeilen und musst folglich auch dreimal Enter drücken. Der Grund ist, dass Du eine Eingabezeile ja solange editieren kannst solange nicht Enter gedrückt wurde. Erst wenn man Enter drückt gilt die Eingabe als abgeschlossen und der Eingabepuffer wird geflusht so dass die Eingabe dem Programm zur Verfügung steht.
    Wenn Du die Daten aus einer Datei einliest wäre das anders.
  • in: Aus GPS Koordinaten Kurs berechnen

    geschrieben von darkpandemic

    Hallo christian1603,

    eigentlich kannst Du die Beispielrechnung aus Wikipedia einfach abschreiben:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    #ifndef M_PI
    static const double M_PI = 3.1415926535897932384626433832795;
    #endif
    
    static const double R_EARTH=6371000.785;
    
    /* define structure for geographic coordinates: */
    typedef struct
    {
      double latitude;
      double longitude;
    } geographic_t;
    
    /* compute the angular distance between two locations.
     *   coord1 -- pointer to coordinates of first location
     *   coord2 -- pointer to coordinates of second location
     *
     *   returns angular distance in radians
     */
    double angular_distance(geographic_t * coord1, geographic_t * coord2)
    {
      double phi_1, phi_2, lambda_1, lambda_2, zeta;
    
      /* convert degrees to radians: */
      phi_1 = coord1->latitude * M_PI / 180.0;
      lambda_1 = coord1->longitude * M_PI / 180.0;
    
      phi_2 = coord2->latitude * M_PI / 180.0;
      lambda_2 = coord2->longitude * M_PI / 180.0;
    
      /* do what Wiki told you: */
      zeta = acos(sin(phi_1)*sin(phi_2)+ cos(phi_1)*cos(phi_2)*cos(lambda_2 - lambda_1));
    
      return zeta;
    }
    
    /* compute the geographic distance between two locations.
     *   coord1 -- pointer to coordinates of first location
     *   coord2 -- pointer to coordinates of second location
     *
     *   returns distance in meters
     */
    double distance(geographic_t * coord1, geographic_t * coord2)
    {
      /* again, do what Wiki told you: */
      return R_EARTH * angular_distance(coord1, coord2);
    }
    
    int main(int argc, char ** argv)
    {
      /* first posibility: */
      geographic_t g1 = {52.011144, 11.68632};
      geographic_t g2 = {51.983611, 11.6922};
    
      printf("Winkel: %.2lf Grad\n", angular_distance(&g1, &g2)*180.0/M_PI);
      printf("Abstand: %.2lf km\n", distance(&g1, &g2)/1000.0);
      
      /* second possibility: */
      g1.latitude = atof("52.011144");
      g1.longitude = atof("11.68632");
    
      g2.latitude = atof("51.983611");
      g2.longitude = atof("11.6922");
    
      printf("Winkel: %.2lf Grad\n", angular_distance(&g1, &g2)*180.0/M_PI);
      printf("Abstand: %.2lf km\n", distance(&g1, &g2)/1000.0);
      
      getchar();
      return 0;
    }
    Allerdings ist das vermutlich nicht das, was Du eigentlich willst.
    Die Formeln geben Dir entweder den Winkelabstand oder den Abstand der zwei Punkte in Metern. Was Du aber nicht bekommst ist die Richtung in die Du gehen musst.
    Idealerweise sollte der Kurs vermutlich als Kompass-Richtung angegeben werden. Dazu sind Großkreise (Orthodrome) nicht geeignet, da sich die Kompassrichtung ständig ändert. Also solltest Du Dir vermutlich das hier anschauen:
    http://de.wikipedia.org/wiki/Loxodrome
  • in: [VB] kompakter & kürzer programmieren

    geschrieben von darkpandemic

    Hallo softtrink,

    neben der Idee mit dem Array oder Listen (wenn die Anzahl variabel ist), kann man die Buttons z.B. auch einfach in ein Panel setzen.
    Dann setzt man einfach das Panel sichtbar bzw. unsichtbar und alle Buttons sind zu sehen oder nicht.
  • in: Unbestimmten Treiber zu installieren

    geschrieben von darkpandemic

    Hallo ventos,

    dass das Installieren funktioniert ist ja ok. Aber weil er beim Starten sagt, dass er die Datei nicht findet, bedeutet das ja, das beim Installieren etwas schief gegangen ist.
    Ich gehe davon aus, dass CreateService() den angegebenen Pfad nicht überprüft, weshalb erst bei StartService() auffällt, dass damit etwas nicht stimmt.
    Falls Du Lust hast, kannst Du mir den vollständigen Code ja irgendwie zukommen lassen, dann probiere ich es bei mir mal aus.

    Edit 1:
    Das erste, was ich festgestellt habe nachdem ich den Treiber für Win7/x64 gebaut habe, ist, dass Win7 keine nicht signierten Treiber mag. Also muss ich erst mal Test Signing aktivieren und rebooten.

    Edit 2:
    Also nachdem ich den Rechner im Test-Modus gestartet habe hat die Sache bei mir funktioniert. D.h. der Service konnte installiert und gestartet werden und zum Glück hat auch das Stoppen und Entfernen funktioniert. Das FileOpen() ist aber fehlgeschlagen.
    Jetzt bleibt die Frage, warum es bei Dir nicht funktioniert.
    Mit welchem Betriebssystem arbeitest Du denn? Der Treiber, den Du mitgeliefert hast war ja für WinXP/32 Bit. Falls Du ein anderes System hast dann musst Du vielleicht einfach den Treiber anders compilieren.
  • in: Unbestimmten Treiber zu installieren

    geschrieben von darkpandemic

    Hallo ventos,

    die Doku sagt, dass man den vollständigen Pfad angeben muss:
    lpBinaryPathName [in, optional]
    The fully qualified path to the service binary file. If the path contains a space, it must be quoted so that it is correctly interpreted. For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"".

    The path can also include arguments for an auto-start service. For example, "d:\\myshare\\myservice.exe arg1 arg2". These arguments are passed to the service entry point (typically the main function).

    Dort steht auch, dass man extra Gänsefüßchen benötigt, wenn man Leerzeichen im Pfad hat. Ist das der Fall?
  • in: Unbestimmten Treiber zu installieren

    geschrieben von darkpandemic

    Hallo ventos,

    laut API-Doc bedeutet das, dass er den Treiber nicht findet.
    Hast Du beim installieren des Treibers den vollständigen Pfad angegeben, also "C:\foo\bar\...", und nicht nur einen relativen Pfad?
    Das könnte vielleicht ein Grund sein.
  • in: Unbestimmten Treiber zu installieren

    geschrieben von darkpandemic

    Hallo ventos,

    welcher Fehlercode wird denn zurückgegeben?
  • in: Hangman: Wie umsetzen?

    geschrieben von darkpandemic

    Hallo fabi755,

    nachdem ich gelegentlich auch das Vergnügen habe Einstellungstests zu bewerten gebe ich einfach mal meinen unverbindlichen Senf dazu:
    Wenn Du mit PHP gut umgehen kannst, dann solltest Du die Aufgabe auch mit PHP umsetzen. Der Grund ist einfach der, dass C++ eine wesentlich komplexere Sprache ist bei der man verflucht viel falsch machen kann wenn man nicht wirklich weiß, was man da tut.
    Sachen die sofort negativ auffallen sind z.B. falsche Verwendung von Zeigern, schlechte Verwendung von Referenzen (als Methoden-Argument/Rückgabewert), falsche bzw. schlechte Verwendung von Strukturen und Klassen, falsche Verwendung von Copy-Konstruktoren, globale Variablen, evtl. noch unnötige Vermischung mit C usw.
    Was den Umfang des Projektes anbetrifft, denke ich, dass Du die Sache eher kurz gestallten solltest. Niemand, der so eine Aufgabe kontrolliert, hat Lust sich durch tausende Zeilen Code zu kämpfen. Zumal eine Lösung mit geringen Umfang ja unter Umständen auch zeigt, dass Du in der Lage bist Dich auf das wesentliche zu konzentrieren und damit effiziente Lösungen findest. Längere Lösungen finde ich nur dann gut, wenn sie eine außergewöhnliche Herangehensweise/Lösung für ein Problem demonstrieren, weil das dann Kreativität zeigt.
    Wichtig ist eher, dass der Code den Du ablieferst ordentlich aussieht und tut was er soll. D.h. leicht verständliche Variablennamen (nicht nur ein Buchstabe oder ein unverständliches Abkürzungsgewirr), einheitlicher Stil (z.B. Durchgängig Pascal- oder Camel-Case oder alles klein mit Unterstrichen), ordentliche Codeformatierung (Einrückung / Klammernpositionen) und Kommentare wo nötig.
    Nachdem Du Dich für eine Ausbildungsstelle bewirbst muss der Code aber sowieso nicht perfekt sein sondern nur zeigen, dass Du grundsätzlich Verständnis für diese Thematik hast und das Potential vorhanden ist daraus etwas zu machen.
    Im Rahmen von PHP würde ich hier wahrscheinlich schlicht mit Session-Variablen und GD für ein Bild arbeiten und das ganze noch ein bisschen mit OOP aufwerten.
    Und wie oben erwähnt sollen alle meine Aussagen als unverbindlich angesehen werden, d.h. mach einfach wobei Du Dich am wohlsten fühlst. Schließlich kann es ja sein, dass die das alles ganz anders sehen als ich.
    Auf jeden Fall wünsche ich Dir viel Erfolg :thumb:







  • in: Excel-Datei in Response mit Java

    geschrieben von darkpandemic

    Hallo hk1992,

    erst mal eine doofe Frage:
    Hast Du mit dem Apache POI schon mal erfolgreich eine Excel-Mappe erstellt, welche Du öffnen konntest?
    Ich hoffe jetzt einfach mal, dass die Antwort auf diese Frage 'Ja' ist. Ansonsten sollte man erst mal eine normale Java-Anwendung schreiben und sicherstellen, dass auch wirklich brauchbare Excel-Mappen erzeugt werden.
    Ansonsten ist jetzt systematisches Debugging angesagt.
    Als erstes sollte man sicherstellen, dass das was in den ByteArrayOutputStream geschrieben wird das selbe ist wie das was auch in die Datei geschreiben wird. D.h. ein Test-Workbook erstellen und erst direkt mittels FileOutputStream in eine Datei schreiben. Danach das selbe Workbook in einen ByteArrayOutputStream schreiben, den Rückgabewert der size()-Methode auf Übereinstimmung mit der Dateigröße überprüfen und dann den ByteArrayOutputStream mittels writeTo()-Methode in einen anderen FileOutputStream kopieren.
    Jetzt kann man beide Dateien noch mit einem Hex-Editor vergleichen (z.B. HxD).
    Wenn beide Dateien übereinstimmen, dann kann man zumindest sagen, dass das erzeugen der Excel-Mappe und das schreiben in den ByteArrayOutputStream nicht das Problem ist.
    Dann bliebe also das kopieren in den OutputStream des HTTPServletResponse bzw. das eigentliche Übertragen übrig.
    Dazu kann man erst mal versuchen, kleinere Datenmengen in den OutputStream zu schreiben. Also z.B. erst eine ByteArray der Größe 16, dann 32, 64 usw. bis 2048, und immer anschauen, was beim Client ankommt. Je nachdem was dabei rauskommt könnte man dann schauen, wo das Problem ist bzw. wie es sich evtl. umgehen lässt.
  • in: Excel-Datei in Response mit Java

    geschrieben von darkpandemic

    Hallo hk1992,

    in diesem Fall macht es keinen Unterschied, ob Du ServletOutputStream oder einfach nur OutputStream verwendest.
    Die Methode HttpServletResponse.getOutputStream() liefert ein Objekt vom Typ ServletOutputStream zurück. Dieses Objekt ist aber von OutputStream abgeleitet, weshalb es natürlich auch ein OutputStream ist.
    Da wir uns hier nur für die Methode flush() interessieren reicht es vollkommen sout als OutputStream zu deklarieren.
    ServletOutputStream bräuchte man nur wenn man die print() und println() Methoden verwenden wollte. Die sind in OutputStream nicht enthalten.
    Im übrigen hat ByteArrayOutputStream eine size() Methode mit der man die Größe erfragen kann. Desweiteren verfügt die Klasse über eine writeTo() Methode mit der sich der Inhalt in einen andere Stream kopieren lässt.
    D.h. man könnte mal folgendes versuchen:
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
    	throws ServletException, IOException {
    	Calendar c1 = Calendar.getInstance();
    	SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyy");
    	String dateStr = sdf.format(c1.getTime());
    	fileName = "Compliance_Report_" + dateStr + ".xlsx";
    
    	Workbook wb = createExportFile(fileName);
    	ByteArrayOutputStream bos = new ByteArrayOutputStream();
    	wb.write(bos);
    
    	resp.setContentLength(bos.size());
    	resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    	resp.setHeader("Content-Disposition", "attachment; filename="+ fileName);
    
    	OutputStream sout = resp.getOutputStream();
    	bos.writeTo(sout);
    	sout.flush();
    	sout.close();
    }
    
    private Workbook createExportFile(String fileName) {
    	Workbook wb = new XSSFWorkbook();
    
    	Sheet s1 = wb.createSheet(WorkbookUtil.createSafeSheetName("Test"));
    	Row r1 = s1.createRow((short) 1);
    	r1.createCell(1).setCellValue("Test");
    
    	return wb;
    }
    Ich habe noch ein sout.close() hinzugefügt, in der Hoffnung, dass das das Problem mit der unvollständigen Datei löst.
  • in: MVC-Pattern spezielles Verständnisproblem

    geschrieben von darkpandemic

    Hallo bigbaer,

    am besten ist es wohl, wenn Du die Listener nur benachrichtigst, wenn auch tatsächlich eine Änderung erfolgt ist.
    Z.B.
    Feld A im Model hat den Wert 'foo'. Der View setzt den Wert 'bar' => Listener benachrichtigen
    Feld A im Model hat den Wert 'bar'. Der View setzt den Wert 'bar' => keine Benachrichtigung da keine Änderung

    Ein guter Moment um den Wert aus einem Textfeld in das Model zu übernehmen ist im übrigen der Fokus-Verlust.
  • in: Excel-Datei in Response mit Java

    geschrieben von darkpandemic

    Hallo hk1992,

    ich würde mal folgendes probieren:
    OutputStream sout = resp.getOutputStream();
    wb.write(sout);
    sout.flush();

  • in: Anfängerfrage zu .dll linking

    geschrieben von darkpandemic

    Hallo makawa,

    ich habe mir mal das aktuelle Code::Blocks heruntergeladen und es ausprobiert.
    Mein Vorgehen war wie folgt:
    1. Neues Projekt angelegt Konsole/C++
    2. Die Dateien sqlite3.c und sqlite3.h in den Projektordner kopiert. Also direkt neben main.cpp
    3. Über den Menüpunkt 'Project -> Add Files...' die beiden Dateien für die Debug und Release Konfiguration hinzugefügt.
    4. Projekt erstellt.
    Lief alles ohne Probleme. Auch das Öffnen und Schließen einer In-Memory Datenbank funktionierte.
    Aber mir scheint, dass Du jetzt auf Linux unterwegs bist. Zumindest schließe ich das aus den Pfaden und aus den fehlenden Referenzen.
    Füge mal zu Deinen Linkeroptionen folgendes hinzu:
    -ldl -lpthread
    Auf den ersten Blick würde ich sagen, dass es damit funktionieren sollte.
  • in: mauszeiger ändern

    geschrieben von darkpandemic

    Hallo superultimatelps,

    Du kannst den Curser entweder per CSS ändern:
    http://www.javascriptkit.com/dhtmltutors/csscursors.shtml
    oder alternativ dynamisch per JavaScript setzen:
    http://stackoverflow.com/questions/3614102/javascript-change-cursor-icon
  • in: Anfängerfrage zu .dll linking

    geschrieben von darkpandemic

    Hallo makawa,

    um SQLite in Dein Programm zu integrieren benötigst Du eigentlich gar keine Dll. Du kannst Dir hier einfach den Quellcode holen. Dazu nimmst Du den obersten Link (sqlite-amalgamation-3071502.zip) und fügst die enthaltene .c und .h Dateien einfach Deinem Projekt hinzu. Dann war es das eigentlich schon.
    Fall Du doch mal mit Dlls zu tun hast:
    Soweit ich weis kann GCC/MinGW direkt gegen Dlls linken. D.h. Du gibst die Dll einfach dort an wo Du auch die .a Dateien für den Linker angibst. Die Dll muss dann nur irgenwo liegen, wo der Linker sie auch findet.
    Zu den Datei-Typen:
    Eine .a Datei ist eine Bibliothek die statisch verlinkt wird. Es gibt .a Archive, welche den vollständigen Code beinhalten und es gibt welche, die nur den Code zum Import einer externen Bibliothek (.dll unter Window, .so unter Linux) beinhalten. Die .a Archive für die Windows-API gehören zum zweiten Typ.
    Eine .def Datei beinhaltet im allgemeinen nur eine Auflistung der von einer Dll exportierten Funktionen. Diese wird aber eigentlich nur von Visual Studio Entwicklungsumgebung verwendet. Eine .lib Datei ist das Analogon zur .a Datei für Visual Studio.
    Allerdings kann MinGW auch .lib Dateien Linken.

    Weitere Links zum Thema:
    http://www.mingw.org/wiki/CreateImportLibraries
    http://www.mingw.org/wiki/Specify_the_libraries_for_the_linker_to_use
  • in: Analogeingänge mit hoher Genauigkeit & Arduino

    geschrieben von darkpandemic

    Hallo fatfox,

    ich habe den Übeltäter gefunden. Es ist die -12V Spannungsquelle die wohl reichlich instabil ist. Ich habe jetzt noch einen 2.2mF Stützkondensator eingebaut und siehe da:
    http://www.abload.de/img/opamp_ergebnis_2hzuhl.png
    Jetzt ist das gewackel nur noch ungefähr +/-1 ;-)
    Allerdings habe ich den ersten Kondensator verpolt worauf er nach kurzer Zeit durch ein zischen sein Ableben bekannt gab :angel:.
    Daher bitte ich noch um eine Minute des Schweigens für die Opfer.
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:
    :frown:

    Danke!
  • in: Analogeingänge mit hoher Genauigkeit & Arduino

    geschrieben von darkpandemic

    Hallo fatfox,

    das Arduino lebt noch, die Netzteile habe sich vertragen und die OpAmps habe ich zu schätzen gelernt;-)
    Ich habe jetzt mal eine Schaltung zurechtgezimmert, die im Grunde das tut was es soll:
    http://www.abload.de/img/opamp_schaltplanvkjkw.png
    Allerdings ist das mit der 'hohen Genauigkeit' wohl etwas mißglückt:
    http://www.abload.de/img/opamp_ergebnisdbu61.png
    Die Ausgabe wackelt um +/-16, was bedeutet, dass die niederwertigen 5 Bit mehr oder weniger Müll sind.
    Nun aber ein paar Details zum Aufbau:
    Mit dem Spannungsteiler R1/R2/R3 habe ich das Eingangssignal simuliert. (Die Spannungsquelle an R1 muss +12V sein. Kleiner Fehler im Plan). In der Praxis konnte ich damit Spannungen von 1.06V bis 4.05V einstellen.
    Der OpAmp U1 mit widerstandsfreier Gegenkopplung dient als Spannungsfolger um das Signal nicht durch die Messung zu beeinflussen.
    Der Spannungsteiler R4/R5/R6 liefert die negative Offset-Spannung. Der 470R Trimpoti zum justieren hat sich dabei als sehr nützlich herausgestellt.
    Der OpAmp U2 erfüllt den gleichen Zweck wie U1.
    Sofern man die Offset-Spannung über einen Spannungsregler erzeugt, kann man auf den Spannungsfolger U2 + Vorbau verzichten.
    Die Verbindung U1/R7/R8/U2 agiert im wesentlichen als Spannungsteiler. Das Signal das dadurch an den nicht-invertierenden Eingang von U3 abgegeben wurde lag zwischen 0V und 1.49V.
    Der OpAmp U3 agiert jetzt als nicht-invertierender Verstärker und hat das Signal auf den Bereich 0V bis 4.96V verstärkt.
    Viel höher wollte ich auch nicht gehen, da der ADC ja auch nicht übersteuert werden soll.
    Jetzt wäre es interessant zu wissen, woher die Störungen eigentlich kommen (Spannungsfolger schlecht? / Spannungsquelle schlecht? / Verstärker schlecht?...). Aber um das zu untersuchen fehlen mir die notwendigen Gerätschaften.
    Von daher hoffe ich jetzt einfach mal, dass Du mit den Infos was anfangen kannst.
    Falls Du selber in dieser Richtung weiterbastelst und rausfindest wo die Güte-Probleme stecken bzw. wie man sie mindern kann, dann würde ich mich über ein Update freuen.

    Edit:
    Noch ein Nachtrag zum Thema Überspannung:
    An Stelle der Zener-Dioden kann man auch Schottky-Dioden verwenden. Die scheinen sogar üblicher zu sein.
    Ein Überspannungsschutz direkt vor dem ADC ist bei genauerer Betrachtung eine schlechte Idee. Wenn man sich z.B. die Kennlinie einer 5.2V Zener-Diode anschaut, dann sieht man, dass diese bereits bei 4V anfängt durchzubrechen. D.h. das Messsystem ist ab 4V aufwärts nicht mehr linear, was bei jeder neu gebauten Schaltung erstmal eine Kalibrierung notwendig machen würde (-> zu aufwändig = zu teuer).
    Wenn man eine Diode mit höherem Wert verwende, z.B. 6.2V oder höher, dann hat man zwar keine Verzerrung des Messergebnisses aber dafür das Risiko, dass der ADC bis zu 6.2V abbekommt. Diese Lösung ist somit erst recht sinnlos.
    Eine Möglichkeit, welche ich jetzt aber nicht aufgebaut habe, wäre, den Verstärker U3 so aufzubauen, dass er bei maximalem Eingangssignal ein maximales Ausgangssignal liefert (volle Aussteuerung). Dahinter kann man dann noch einen Spannungsfolger gefolgt von einem Spannungsteiler setzen. Weil man die maximale Ausgangsspannung des Spannungsfolgers kennt kann man den Spannungsteiler so dimensionieren, dass es unmöglich zu einer Überspannung kommen kann (außer das Netzteil spinnt).
    Dann bliebe nur noch die Absicherung des Einganges an U1. Das ist aber wesentlich einfacher, da ein normales Signal maximal 5V betragen soll und der OpAmp bis zu 12V als Eingangsspannung verkraftet. Hier kann man dann z.B. eine 6.8V Zener-Diode einsetzen ohne das Signal zu stören und ohne den OpAmp zu riskieren.
    Im übrigen habe ich hier noch ein paar Schaltungen gefunden:
    http://www.dg1asc.de/scrap/nuts_ps2.htm

  • in: Analogeingänge mit hoher Genauigkeit & Arduino

    geschrieben von darkpandemic

    Hallo fatfox,

    das Multimeter meldet 16.8mV Potentialdifferenz zwischen den Massen. Das wird mein Rechner hoffentlich überleben;-)
    Nachdem ich die die Frage gepostet habe, habe ich mir natürlich auch gleich ans Hirn gefasst, da ich mir die Antwort auf Frage 2 weiter oben ja eigentlich schon selber gegeben habe.
    Nur habe ich leider kein Zenner-Dioden und Sicherungen da. Also muss ich wohl erstmal ein bisschen Shoppen.
  • in: Analogeingänge mit hoher Genauigkeit & Arduino

    geschrieben von darkpandemic

    Hallo miteinander,

    inspiriert vom Thema habe ich hier mal einen LM358 aufs Board gestöpselt um die Sache auszuprobieren. Dabei bin ich leider schon am Anfang steckengeblieben. Der Spannungsfolger funktioniert eigentlich wunderbar, aber leider nur bis 3.82V wenn ich ihn mit den 5V vom Arduino versorge. D.h. ich benötige eine höhere Versorgungsspannung.
    Und jetzt gleich die eigentliche Frage:
    Ich habe hier ein umgerüstetes Computernetzteil, welches ich verwenden könnte um den OpAmp mit 12V zu versorgen. Dazu muss man dann natürlich den Arduino GND (=GND meines PC's) mit dem Netzteil GND verbinden. Weis jemand, ob es dabei Ärger geben kann oder ob sich die Netzteile soweit vertragen?
    Alternativ habe ich hier noch ein Schaltnetzteil aus einem Drucker, dass 24V liefert.
    Die nächste Frage ist, wie man das Arduino dann gegen den OpAmp absichert. Der könnte ja dann weit mehr als 5V ausspucken.
  • in: Analogeingänge mit hoher Genauigkeit & Arduino

    geschrieben von darkpandemic

    Hallo fatfox,

    ich habe nochmal etwas rumgesucht, ob es eine professionellere Lösung für das Problem gibt. Da in Messgeräten ja häufig OpAmps für alles mögliche verbaut sind habe ich mal in dieser Richtung gesucht. Und ich glaube ich habe da was:
    http://www.ecircuitcenter.com/Circuits/opsum/opsum.htm
    Du musst nur irgenwo eine negative Spannung herbekommen, dann kannst Du den analog Offset sogar über einen Poti einstellbar machen.

    Edit:
    Eventuell benötigst Du auch noch einen Spannungsfolger damit sich der Messwiederstand und die Wiederstände des Summierverstärkers nicht beeinflussen.
  • in: Analogeingänge mit hoher Genauigkeit & Arduino

    geschrieben von darkpandemic

    Hallo fatfox,

    ich schreibe jetzt einfach mal einen unqualifizierten Kommentar:
    Ich habe gerade mal mit einer 1N4004 Diode versucht den Analog-Offset abzusenken. Eine Diode verringert den Pegel um 0,25V.
    Wenn man also über einen Widerstand mit 312,5 Ohm misst (V_min=1,25V / V_max=6,25V) und den Pegel über 5 Dioden (Offset=-1,25V) auf den Analogeingang des Arduino legt, dann hat man (zumindest theroretisch) die vollen 1024 Schritte zur Verfügung.
    Was die Absicherung betrifft, denke ich nicht, dass es möglich ist eine galvanische Trennung zwischen Sensor und Arduino zu verwirklichen sofern man die Analogeingänge verwenden will. Man kann aber eine Zenner-Diode gegen Überspannung und dazu noch eine Feinsicherung gegen zu hohe Ströme einsetzen.
    Alternativ kann man wohl eine externen ADC + analog Multiplexer verwenden, welchen man dann wieder mit den üblichen Mitteln absichert. Aber die Zenner-Diode und die Feinsicherung wird man zum Schutz von ADC und Multiplexer wohl trotzdem benötigen. Es sei den man bekommt die Bausteine irgendwo billig nachgeworfen.
    Zur Genauigkeit:
    Ob Dir ein ADC mit höherer Genauigkeit überhaupt etwas bringt hängt von der Messgenauigkeit des Sensors ab. Damit die 891 Schritte des ersten Ansatzes signifikant sind, darf der Sensor nur eine Ungenauigkeit von unter +/-20µA haben. Wenn man von 1024 Schritten ausgeht, dann müssen es weniger als +/-15µA sein. Als Temperatur also +/-1.1°C bzw. +/-1.0°C.
    Falls die Genauigkeit des Sensors geringer ist, dann sind die niederwertigen Bits sowieso nur Schrott und ein ADC mit höherer Auflösung bietet keinen Mehrwert.
    Ich hatte hier mal eine Temperatursensor (allerdings Infrarot) der ist problemlos um +/- 2°C gesprungen. Und der gehörte wohl schon zu den besseren.
    Um ein verlässliches Ergebnis zu bekommen musste man dabei sowieso über mehere Messungen mitteln. Unter Umständen trifft das auch für Deine Sensoren zu.

    Edti: Tausche Bit gegen Schritte.
  • in: Aufruf meines Java Programms

    geschrieben von darkpandemic

    Hallo qwertz,

    schau mal hier:
    http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
    'java.home' sollte dein Freund sein.
    Das '/bin/java' musst Du aber wahrscheinlich selber noch einfügen.
  • in: TheoInf: lexikografische Ordnung

    geschrieben von darkpandemic

    Hallo myhead,

    die Antwort auf Frage 1) ist nicht korrekt. Du hast ja schließlich keinen Buchstaben aus dem Alphabet entfernt. Daher ist es:
    Formel: N^* = 10^1+10^2+10^3+10^4
    Mit dem leeren Wort, also einem Wort mit 0 (Null) Buchstaben wäre es:
    Formel: N = 10^0+10^1+10^2+10^3+10^4 = 10^0+N^* = 1+N^*
    Bei Aufgabe 2) sollte noch ein Wort gegeben sein, da das Alphabet selbst keine Position hat sondern eine Ordnung definiert.
    Sofern es bei Aufgabe 3) keine Einschränkungen gibt, ist es das Wort, das aus 999 a's besteht.
  • in: VB Strings speichern

    geschrieben von darkpandemic

    Hallo softtrink,

    wenn Du Deinen Benutzern das Backup erleichtern willst, dann speicherst Du alle Einstellungen am besten in einer Datei im Application-Data-Verzeichnis des Benutzers.
    Den Pfad bekommst Du über:
    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
    Siehe dazu hier und hier.
    Darin legst Du dann einen Ordner für Dein Programm an und speicherst darin die Dateien.
    Der Vorteil ist, dass der Benutzer nur den Ordner sichern muss um alle relevanten Daten zu haben und er die Einstellungen so auch einfach auf andere Systeme umziehen kann.
    Von daher bevorzuge ich diese Lösung normalerweise gegenüber der Registrierdatenbank.
  • in: HEX-Code über TCP/IP versenden

    geschrieben von darkpandemic

    Hallo schrotti12,

    den gesamten C-Code zu posten würde den Rahmen hier vollständig sprengen. Es war auch eher als Pseudo-Code Vorlage gedacht.
    Aber hier ist die entsprechende Java Version:
    package test;
    
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Main
    {
      private static String bytesToHex(byte[] bytes)
      {
        StringBuilder sb = new StringBuilder();
            
        for(int i = 0; i<bytes.length; i++)
        {
          sb.append(String.format("%02X", bytes[i]));
        }
        return sb.toString();
      }
        
      public static void main(String[] args)
      {
        try
        {
          try (ServerSocket listener = new ServerSocket(1234);
               Socket sok = listener.accept();
               InputStream is = sok.getInputStream())
          {
            byte bytes[] = new byte[6];
            is.read(bytes);
                    
            System.out.println(bytesToHex(bytes));
          }
        }
        catch(Exception e)
        {
          System.err.println(e.getMessage() + e.getStackTrace());
        }
      }
    }

    Im Übrigen habe ich hier noch die Protokollspezifikation gefunden:
    http://www.vandomburg.nu/useruploads/files/mdc_ue_me_de_protocol_ver_063-eng.pdf
    Das macht die Sache hoffentlich einfacher.

    Edit: Hat es eigentlich einen Grund, dass Du den Socket-Stream noch einmal in einem DataOutputStream verpackst? Fall nicht, dann lass den besser weg, weil der nur unnötigen Overhead erzeugt.

    Edit2: Blödsinn entfernt.


  • in: HEX-Code über TCP/IP versenden

    geschrieben von darkpandemic

    Hallo schrotti12,

    ich habe mal folgendes kleines Java-Programm zusammengestöpselt:
    package test;
    
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class Main
    {
      private static byte[] hexToBytes(String hex) throws Exception
      {
        if(hex.length()%2 == 1)
        {
          throw new Exception("Hex string has an invalid size.");
        }
            
        byte chars[] = hex.getBytes();
        byte result[] = new byte[chars.length / 2];
            
        for(int i=0; i<chars.length; i++)
        {
          result[i/2] <<= 4;
                
          if(chars[i] >= '0' && chars[i]<= '9')
          {
            result[i/2] += (byte) (chars[i] - '0');
          }
          else if(chars[i] >= 'a' && chars[i]<= 'f')
          {
            result[i/2] += (byte) (chars[i] - 'a' + 10);
          }
          else if(chars[i] >= 'A' && chars[i]<= 'F')
          {
            result[i/2] += (byte) (chars[i] - 'A' + 10);
          }
          else
          {
            throw new Exception("Hex string contains invalid characters.");
          }
        }
            
        return result;
      }
        
      public static void main(String args[])
      {
        try
        {
          byte msg[] = hexToBytes("AA1103010015");
          Socket sok = new Socket("127.0.0.1", 1234);   
          try (OutputStream os = sok.getOutputStream())
          {
            os.write(msg);
          }
        }
        catch(Exception e)
        {
          System.err.println(e.getMessage() + e.getStackTrace());
          return;
        }
      }
    }
    Als Gegenstelle habe ich ein kleines C-Programm genommen:
    int main(int argc, char ** argv)
    {
      long i;
      WSADATA wsa_data = {0};
      TcpListener listener;
      TcpSocket sok;
      unsigned char bytes[6];
    
      WSAStartup(MAKEWORD(2,2), &wsa_data);
    
      listener = TcpListener_Create();
      TcpListener_SetPort(listener, "1234");
      TcpListener_SetTimeout(listener, 10000);
      TcpListener_Start(listener);
    
      while(!(sok = TcpListener_Accept(listener)));
    
      Stream_Read(sok, bytes, sizeof(bytes));
      Stream_Free(sok);
    
      TcpListener_Free(listener);
    
      for(i=0; i<sizeof(bytes); i++)
        printf("%02X", bytes[i]);
    
      getchar();
      WSACleanup();
      return 0;
    }
    Angekommen ist folgendes:
    AA1103010015

    Somit würde ich sagen, dass obiges Programm eigentlich funktionieren sollte.
    Das ein Packet bei der Übertragung zerteilt wird kann jederzeit passieren. Wenn der Server damit nicht klar kommt, dann ist der Server einfach Schrott. Desweiteren kannst Du dagegen auch nicht wirklich viel machen, da das Betriebssystem bzw. der Treiber und die Netzwerkkarte darüber entscheiden, wann und wieviele Daten übertragen werden.
  • in: Problem bei Installation von MS Visual Studio 2012

    geschrieben von darkpandemic

    Hallo luukkkiiii,

    hast Du den Online- (Jetzt installieren!-Link) oder den Offline-Installer (Jetzt herunterladen!-Link)?
    Falls es der Online-Installer ist, dann würde ich es mal mit dem Offline-Installer versuche. Falls es bereits der Offline-Installer ist würde ich Ihn nochmal herunterladen. Vielleicht ist ja die Datei unvollständig oder anderweitig beschädigt.
  • in: Assembler - Zahl in Gleitkommadarstellung

    geschrieben von darkpandemic

    Hallo toolz,

    was steht den bei Dir in ebx? Es klingt ja fast so, als ob sich dort der Integer befindet. Für fild muss sich in ebx aber die Adresse des Speicherbereiches befinden in welchem der Integer liegt und für fstp die Adresse des Speicherbereiches in dem der float abgelegt werden soll. Die Speicherbereiche müssen jeweils 4 Byte groß sein.
    Das sollte in FASM ungefähr so aussehen, wenn Du vorher zwei Variablen int_val und float_val angelegt hast:
    label int_val
    dd 0
    label float_val
    dd 0
    ...
    mov ebx, int_val
    fild dword[ebx]
    mov ebx, float_val
    fstp dword[ebx]

    Edit: Evtl. kannst Du es auch mit SSE machen:
    label int_val
    dd 0
    label float_val
    dd 0
    ...
    mov eax, dword[int_val]
    cvtsi2ss xmm0, eax
    mov eax, float_val
    movss dword[eax], xmm0

    Mehr dazu kannst Du hier und hier nachlesen.

    Edit2: Es müssen natürlich Doppelworte und keine Quadworte sein.
  • in: Java - String beim hashen fehlerhaft

    geschrieben von darkpandemic

    Hallo devalistic,

    Du verlierst beim Konvertieren von Integer nach String die führenden Nullen. Versuche mal folgendes:
    sb.append(String.format("%02x", b));

    Mehr zum Thema findest Du hier.
  • in: Filmgeschichte: Meilensteine der Komödien?

    geschrieben von darkpandemic

    Mir fällt dazu noch eine nette Komödie von Billy Wilder aus dem Jahr 1961 ein:
    Eins, Zwei, Drei
    Kennt wahrscheinlich kaum noch einer, ist aber ein super Film.

    Edit: Noch ein Tipp zu den 60ern: Jerry Lewis mit Dean Martin,
  • in: Problem mit Select bei PureBasic

    geschrieben von darkpandemic

    Hallo audiogames,

    die Input()-Anweisung liefert Dir einen String zurück aber Deine Case-Anweisungen prüfen auf Integer. Deshalb landest Du immer im Default-Fall. Desweiteren willst Du ja eigentlich die Eingabe des Benutzers prüfen, welche ja a, b oder c nicht aber 1, 2 oder 3 sein soll.
    Falls PureBasic mit String in Select/Case umgehen kann, dann kannst Du einfach folgendes machen:
    Select Input()
      Case "a"
      ...
      Case "b"
      ...
      Case "c"
      ...
      Default
      ...
    EndSelect
    Die Zeilen mit Input = a, Input = b bzw. Input = c brauchst Du gar nicht. Alternativ kannst Du ja auch mit If arbeiten:
    eingabe = Input()
    If eingabe = "a"
      ...
    ElseIf eingabe = "b"
      ...
    ElseIf eingage = "c"
      ...
    Else
      ...
    EndIf
  • in: Eigenartiges Problem mit LastIndexOf

    geschrieben von darkpandemic

    Hallo yorecords,

    da die LastIndexOf-Suche von hinten nach vorne durchgeführt wird musst Du als Startindex den letzten/größten zu durchsuchenden Index angeben. Insbesondere muss der Startindex größer als die Länge des zu suchenden Strings sein.
    Korrekt muss es also lauten:
    int index1 = fileContent.LastIndexOf("a", StringComparison.InvariantCulture);
    
    int index = -1;
    if(index1 > 0)
      index = fileContent.LastIndexOf("a", index1-1 StringComparison.InvariantCulture);

  • in: Einfach vertrackte Liste

    geschrieben von darkpandemic

    Hallo toolz,

    Du solltest lieber zwischen den Ketten-Elementen und dem Kontainer unterscheiden, dann wird die Sache wesentlich einfacher:
    #include <stdio.h>
    #include <stdlib.h>
    
    /* Elemente der Kette */
    typedef struct ketten_element_
    {
      struct ketten_element_ * weiter;
      char * zeile;
    } ketten_element_t;
    
    /* Kontainer für Kettenelemente */
    typedef struct kette_
    {
      ketten_element_t * kopf;
      long anzahl;
    } kette_t;
    
    void kette_init(kette_t * kette) {
        kette->kopf = NULL;
      kette->anzahl = 0;
    }
    
    void kette_merken(char *z, kette_t * kette) {
      ketten_element_t * neu;
    
      neu = (ketten_element_t*)malloc(sizeof(ketten_element_t));
      neu->weiter = kette->kopf;
      neu->zeile = z;
    
      kette->kopf = neu;
      kette->anzahl++;
    }
    
    char * kette_erinnern(kette_t * kette) {
      ketten_element_t * alt;
      char * zeile;
    
      if(!kette->anzahl)
        return "";
        
      alt = kette->kopf;
      kette->kopf = alt->weiter;
      kette->anzahl--;
    
      zeile = alt->zeile;
      free(alt);
      return zeile;
    }
    
    int main(int argc, char ** argv)
    {
      kette_t test;
    
      kette_init(&test);
    
      kette_merken("hallo 1\n", &test);
      kette_merken("hallo 2\n", &test);
      kette_merken("hallo 3\n", &test);
    
      while(test.anzahl)
      {
        printf(kette_erinnern(&test));
      }
    
      getchar();
      return 0;
    }
    Fehlerbehandlung habe ich jetzt wegen der Übersichtlichkeit weggelassen.
  • in: [c#] Verschlüsselung von Dateien

    geschrieben von darkpandemic

    Hallo ventos,

    das .Net-Framework liefert doch schon einen ganzen Haufen Algorithmen mit:
    http://msdn.microsoft.com/de-de/library/system.security.cryptography.aspx
    Da kannst Du Dir ja was aussuchen.
    Und wenn der Algorithmus einen Schlüssel bestimmter Länge verlangt, dann kannst Du ja aus einem eingegebenen Passwort erst einen Hash erzeugen und diesen als Schlüssel verwenden.

    Edit: Hier noch etwas Beispielcode:
    http://ashwinrayaprolu.wordpress.com/2011/03/04/aes-encryption-sample-in-c-csharp/
  • in: modulare arithmetik

    geschrieben von darkpandemic

    Hallo nicolas-k,

    um Mathe-Übungsblätter zu lösen ist es immer eine gute Idee seine Nase in die Vorlesung zu stecken und sich die Definitionen rauszusuchen. Für Aufgabe i) solltest Du dann z.B. folgendes finden:
    Definition Rest:
    Formel: \text{Sei }m \in \mathbb{Z} \setminus \{0\}\text{ und } a \in \mathbb{Z} \text{ beliebig.}
    Formel: \text{Dann gilt:}
    Formel: \exists ! r \in \{ 0, 1, \dots , m-1\} \wedge \exists n \in \mathbb{Z} : a = n\cdot m + r \text{    (1)}
    Formel: R_m(a) := r \text{ ist der Rest der Division von }a\text{ und }m.
    Andererseits sollte sich irgendwo die Definition von Kongruenz finden lassen:
    Formel: a \equiv_m b  \Leftrightarrow \exists k \in \mathbb{Z} : a = k \cdot m + b \text{    (2)}
    Mit Hilfe der Definitionen (2) kannst Du die Kongruenz jetzt umschreiben:
    Formel: a \equiv_m R_m(a) \Leftrightarrow  \exists k \in \mathbb{Z} : a = k \cdot m + R_m(a) \text{    (3)}
    und der Vergleich mit (1) zeigt sofort, dass die Aussage zutrifft, da die rechte Seite von (3) mit der Bedingung aus der Rest-Definition übereinstimmt.
    Die anderen drei Aufgaben lassen sich dann nach dem gleichen Schema lösen: Definition einsetzen und umformulieren bis das gleiche da steht.

    Viel Erfolg!
  • in: Java Array Fehler

    geschrieben von darkpandemic

    Hallo nilsmargotti,

    das reicht auch bei eindimensionalen Arrays nicht. Du hast nur das Glück, dass String.split() ein neues Array zurückliefert.
    Ansonsten musst Du Arrays eigentlich auch mit 'new' anlegen.
    Hier ein kleiner Link zum Thema:
    http://www.go4expert.com/forums/showthread.php?t=1162
  • in: BigInteger: Die integrale Konstante ist zu groß

    geschrieben von darkpandemic

    Hallo yorecords,

    ein bisschen Beispielcode, der das Problem reproduziert könnte nicht schaden ;-)
    Ich denke mal, dass das Problem beim initialisieren auftritt, weshalb es interessant wäre zu erfahren, wie Du das machst.
  • in: C# || Argument mit Leerzeichen an Konsole übergeben

    geschrieben von darkpandemic

    Hallo adelwoehrer,

    das Korrekte escapen von Kommandozeilenargumenten unter Windows ist gar nicht so einfach. Das liegt daran, dass das Betriebssystem dieses Konzept eigentlich gar nicht kennt und von sich aus auch gar nicht unterstützt.
    Die Folge davon ist, dass die Interpretation bzw. Zerlegung der übergebenen Kommandozeile vollständig im Verantwortungsbereich der aufgerufenen Anwendung liegt.
    Falls die aufgerufene Anwendung diese Zerlegung mittels GetCommandLine() und CommandLineToArgvW() macht (was bei den meisten Anwendungen der Fall sein sollte), dann kann Dir evtl. folgender Code helfen:
    static bool escape_argument(StringBuilder cl, const char * argument)
    {
      if( String_Contains(argument, " ") ||
        String_Contains(argument, "\t") ||
        String_Contains(argument, "\n") ||
        String_Contains(argument, "\v") ||
        String_Contains(argument, "\"") ||
        String_GetLength(argument) < 1)
      {
            StringBuilder_Append(cl, "\"");
    
        while(true)
        {
          long count_bs = 0;
    
          while(*argument == '\\')
          {
            count_bs++;
            argument++;
          }
    
          if(!(*argument))
          {
            if(count_bs && !StringBuilder_AppendMultiple(cl, "\\", 2*count_bs))
            {
              fprintf(stderr, "Error: Process::escape_argument: StringBuilder_AppendMultiple() failed.\n");
              return false;
            }
    
            break;
          }
          else if(*argument == '"')
          {
            if(!StringBuilder_AppendMultiple(cl, "\\", 2*count_bs+1))
            {
              fprintf(stderr, "Error: Process::escape_argument: StringBuilder_AppendMultiple() failed.\n");
              return false;
            }
    
            if(!StringBuilder_AppendChar(cl, '"'))
            {
              fprintf(stderr, "Error: Process::escape_argument: StringBuilder_AppendChar() failed.\n");
              return false;
            }
          }
          else
          {
            if(count_bs && !StringBuilder_AppendMultiple(cl, "\\", 2*count_bs))
            {
              fprintf(stderr, "Error: Process::escape_argument: StringBuilder_AppendMultiple() failed.\n");
              return false;
            }
    
            if(!StringBuilder_AppendChar(cl, *argument))
            {
              fprintf(stderr, "Error: Process::escape_argument: StringBuilder_AppendChar() failed.\n");
              return false;
            }
          }
    
          argument++;
        }
    
        if(!StringBuilder_AppendChar(cl, '"'))
        {
          fprintf(stderr, "Error: Process::escape_argument: StringBuilder_AppendChar() failed.\n");
          return false;
        }
      }
      else
      {
        if(!StringBuilder_Append(cl, argument))
        {
          fprintf(stderr, "Error: Process::escape_argument: StringBuilder_Append() failed.\n");
          return false;
        }
      }
    
      return true;
    }
    
    static bool build_command_line(Process pr)
    {
      long i;
      StringBuilder cl = pr->command_line;
    
      StringBuilder_Clear(cl);
    
      if(!escape_argument(cl, pr->exe_path))
      {
        fprintf(stderr, "Error: Process::build_command_line: escape_argument() failed.\n");
        return false;
      }
    
      for(i=0; i<pr->arguments->size; i++)
      {
        if(!StringBuilder_AppendChar(cl, ' '))
        {
          fprintf(stderr, "Error: Process::build_command_line: StringBuilder_AppendChar() failed.\n");
          return false;
        }
    
        if(!escape_argument(cl, pr->arguments->value[i]))
        {
          fprintf(stderr, "Error: Process::build_command_line: escape_argument() failed.\n");
          return false;
        }
      }
    
      return true;
    }
    Das ist jetzt zwar C Code aber der sollte sich ziemlich einfach nach C# übersetzen lassen. Der StringBuilder kann einfach durch die C# StringBuilder-Klasse und die analogen Methoden ersetzt werden. Das 'const char *' kannst Du durch string ersetzen und anstelle von '*argument' musst Du dir noch einen Index anlegen und z.B. per Substring das Zeichen extrahieren.
  • in: Java-Midi-Synthesizer funktioniert nicht

    geschrieben von darkpandemic

    Hallo askarian,

    bei mir läuft Dein Code einwandfrei und spielt auch "Alle meine Entchen".
    Vielleicht hat Deine Java-Installation ein Problem. Ich habe hier JDK und JRE in Version 1.7.0 Update 7 (jeweils 64-bit).
    Vielleicht mal updaten / neu installieren.
  • in: iCommand Vision: Shapes erkennen

    geschrieben von darkpandemic

    Hallo askarina,

    wenn iCommand sich hierauf bezieht, dann hast Du erst einmal Pech, da dort nichts zur "Shape"- bzw. Objekterkennung dabei ist. Eigentlich scheint es noch schlimmer zu sein, da ich noch nicht einmal eine Methode finden kann, die es erlaubt an die Daten eines Frames/Bildes zu kommen.
    Ob die Erkennung von "Shapes" einfach zu machen ist hängt davon ab, was Du darunter verstehst bzw. wie das zugrunde liegende Bildmaterial eigentlich aussieht. Wenn man z.B. nur dunkle Objekte vor einem hellen Hintergrund erkenne will, dann würde es wohl erstmal eine Segmentierung mittels Schwellwert gefolgt von Komponenten-Labeling tun. Wenn Du aber bekannte Objekte in einer inhomogenen Umgebung wiedererkennen willst, dann brauchst Du sowas: SURF-Feature-Detector
    Allerdings ist das zum einen mit einem ganzen haufen Programmieraufwand verbunden, wenn man es selber machen will, und zum anderen benötigt man für sowas 5000+ Testbilder um den Klassifizierer einzulernen (was mitunter mehere Tage dauern kann).
    Wenn Du Dein Glück dennoch Versuchen willst, dann kannst Du es ja mal mit OpenCV versuchen, die habe das alles implementiert und zumindest für Gesichter liegt (Gerüchten zu folge) ein eingelernter Datensatz bei. Um OpenCV von Java aus zu verwenden müsstest Du Dir noch JavaCV besorgen.


  • in: Mit PHP aktuellen Börsenkurs auslesen und speichern

    geschrieben von darkpandemic

    Hallo mf-hd,

    yahoo bietet nur einen RSS-Feed an. Aber wenn es nur Tagesaktuell sein muss, dann kannst Du mithilfe der "Historical Prices" eine CSV-Datei laden.
    Hier z.B. für BASF:
    http://finance.yahoo.com/q/hp?s=BAS.DE&a=09&b=2&c=2012&d=09&e=3&f=2012&g=d
    Der Download-Link ist unten auf der Seite -> "Download to Spreadsheet"
    Die zugehörige URL ist z.B.:
    http://ichart.finance.yahoo.com/table.csv?s=BAS.DE&a=09&b=2&c=2012&d=09&e=3&f=2012
                                                |        |    |   |      |    |   |      
                                                |        |    |   |      |    |   Endjahr
                                                |        |    |   |      |    Endtag
                                                |        |    |   |      Endmonat
                                                |        |    |   Startjahr
                                                |        |    Starttag
                                                |        Startmonat
                                               Aktienkürzel
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    ich habe mal reingeschaut und mein Debugger sagt fogendes:
    http://www.abload.de/img/vier_gewinnt9kkgd.jpg
    D.h. es gibt zwar die Felder mousePanel und gameFrame, diese sind aber nicht zugewiesen. Mit denen müsste man eigentlich das gleiche wie mit dem stonePanel machen: Setter schreiben und in CreateGame.load() zuweisen.
    Der nächste Punkt ist, dass Stone.gameField null ist. Das ist erstmal die Ursache für die Exception. Ich werde Morgen mal schauen, wie sich das evtl. beheben lässt.
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    jetzt sind wir ja schon einen Schritt weiter: Wir wissen, dass computerZug() aufgerufen wird.
    Jetzt kannst Du ja mal schauen, was in Game.java in Zeile 41 steht. Das sollte in der Methode computerZug() sein. Entweder ist das Objekt oder eines der übergebenen Methodenargumente null.
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    kann es sein, dass Du die Game.computerZug()-Methode nirgends aufrufst?
    Füge mal in MousePanel.mousePressed() nach
    Stone stone = new Stone(y, game, this, frame);
    stone.setBounds(clickedOnField * 50 + (clickedOnField + 1) * 2, -50, 50, 50);
    stonePanel.add(stone);
    stonePanel.repaint();
    listenerBlocked = true;
    stone.start();
    game.setStoneToField(clickedOnField, y, stone);
    noch die Zeile
    game.computerZug()
    ein.
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    Du musst mit dem stonePanel einfach das gleich machen wie mit dem mousePanel und dem gameFrame. D.h. irgenwo in der Game-Klasse noch
    private JPanel stonePanel;
    einfügen. Dazu noch einen Setter:
    public void setStonePanel(JPanel panel) {
        stonePanel = panel;
    }
    In der load()-Methode der CreateGame-Klasse fügst Du dann nach
    JPanel stonePanel = new JPanel(null);
    stonePanel.setBounds(0, 0, 366, 314);
    stonePanel.setOpaque(false);
    gamePanel.add(stonePanel, 0);
    noch folgende Zeile ein:
    game.setStonePanel(stonePanel);

    Damit sollte vermutlich folgender Code zum Hinzufügen des Steines funktionieren:
    Stone stone = new Stone(y, this, this.mousePanel, this.gameFrame);
    stone.setBounds(x * 50 + (x + 1) * 2, -50, 50, 50);
    this.stonePanel.add(stone);
    this.stonePanel.repaint();
    stone.start();			
    game.setStoneToField(x, y, stone);
    (Ich hoffe jetzt mal, dass Du das mousePanel und den gameFrame auf ähnliche Weise gesetzt hast. Du kannst naturlich auch einfach public-Felder verwenden.)
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    laut static void load() in der CreateGame-Klasse hast Du ein stonePanel und das wird z.B. auch an den Konstruktor des MousePanels übergeben. Im übrigen wird es auch im mousePressed()-Handler benutzt.
  • in: 15pin zu 15pin Adapter für Joystick gesucht

    geschrieben von darkpandemic

    Hallo norbi,

    wie wäre es hiermit:
    http://www.reichelt.de/Gender-Changer/COM-993/3/index.html?;ARTICLE=6765
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    vielleicht spielt der Computer aber Du siehst es nicht, weil das Label außerhalb des Panels ist. Du kannst ja mal versuchen folgendes einzufügen:
    Stone stone = new Stone(y, this, this.mousePanel, this.gameFrame);
    stone.setBounds(x * 50 + (x + 1) * 2, y*50, 50, 50);
    stonePanel.add(stone);
    stonePanel.repaint();
    setStoneToField(x, y, stone);
    Allerdings musst Du dafü auch noch das stonePanel durchschleusen. (Genauso wie mousePanel und gameFrame)
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    ggamee hat im wesentlichen recht. Das einfachste ist wohl, wenn Du einfach den Code aus dem mousePressed()-Handler der MousePanel-Klasse übernimmst:
    Stone stone = new Stone(y, this, <mousePanel>, <gameFrame>);
    game.setStoneToField(x, y, stone);
    Allerdings ist das auch etwas schwierig, da Du mousePanel und gameFrame in der Game-Klasse nicht kennst. Du könntest aber in der Game-Klasse noch Felder für mousePanel und gameFrame einfügen, auf die jeweiligen Objekte festlegen und die Felder dann für den Stone-Konstruktor verwenden.
    Insgesamt ist das hier leider etwas schwierig, da das Programm-Design gelinde ausgedrückt etwas ungünstig ist.
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    Du musst wahrscheinlich bei setStoneToField() ein Stone-Objekt als drittes Argument an Stelle von null übergeben. Sonst wird da ja nichts gesetzt.
  • in: Ki für Spiel

    geschrieben von darkpandemic

    Hallo kill-a-teddy,

    Du prüfst ja nur auf eine ganz bestimmte Konstellation:
    1 1 1 0
    1 1 1 1

    und solange diese nicht vorliegt passiert auch nichts. Desweiteren musst Du mit Deinen Rändern aufpassen. Es kann nämlich sein, dass es die x+1, x+2 bzw. y+1 Felder gar nicht gibt und dann sollte das eigentlich zu einer Index out of Bounds Exception führen.

    Edit:
    Und wenn die Konstellation vorliegt, dann setzt Du den Stein an eine Stelle, an der bereits einer ist. Es soll wohl eher:
    setStoneToField(x+3,y, null);
    sein.
  • in: Wie geht ihr mit der Ungenauigkeit von Double um?

    geschrieben von darkpandemic

    Hallo yorecords,

    man kann Werte von Anfang an als decimal deklarieren. Dazu musst Du nur ein 'm' dranhängen:
    decimal x = 1.522m;

    Nun zum eigentlichen Thema:
    Was berechnest Du denn eigentlich (+, -, *, / oder auch sin(), cos(), log(), sqrt() etc.) und was verstehst Du unter 'exakte Zeitangabe' (+/-1s, +/-1ms, +/-1µs). Wie groß ist den der Gesamte zu betrachtende Zeitraum (1 Jahr, 100 Jahre, Millionen Jahre, ...)?
    Man hat ja bei double bereits 15 signifikante Stellen, d.h. bei einer Genauigkeit von +/-1µs sollte sich ja innerhalb eines Zeitraumes von 31 Jahren halbwegs exakt rechnen lassen.
    Wenn Du ein paar Infos rausrückst, kann man vielleicht auch eine Lösung finden.

    Edit:
    Hast Du Dir schonmal den DateTime-Type angeschaut?
  • in: C++ Pointer will nicht SDL_Surface

    geschrieben von darkpandemic

    Hallo qwertz4,

    wenn Du den Zeiger als Ausgabeparameter haben willst, dann musst Du die Adresse in welcher der Zeiger gespeichert werden soll übergeben:
    bool loadJPG(SDL_Surface ** sf_img, const char* imgpath){
      //Load image 
      SDL_Surface*  loaded_image = NULL;
      SDL_RWops*    rwop        = NULL;
      printf("Loading Image: %s\n", imgpath);
      rwop=SDL_RWFromFile(imgpath, "rb");
      loaded_image=IMG_LoadJPG_RW(rwop);
      if(!loaded_image) {
        printf("Faild to load Image: '%s'. IMG_LoadJPG_RW returned Error: %s\n", imgpath, IMG_GetError() );
        return false;
      }
      //Create an optimized image 
      *sf_img = SDL_DisplayFormat( loaded_image );
      SDL_FreeSurface(loaded_image);
      SDL_FreeRW(rwop);
      return true;
    }
    Aufrufen musst Du es dann mit
    bool rc=loadJPG(&splash, "../gfx/sdl.jpg" );
    Alternativ kannst Du aber auch einfach den Zeiger als Rückgabewert angeben:
    SDL_Surface * loadJPG(const char* imgpath){
      //Load image 
      SDL_Surface*  loaded_image, result;
      SDL_RWops*    rwop        = NULL;
      printf("Loading Image: %s\n", imgpath);
      rwop=SDL_RWFromFile(imgpath, "rb");
      loaded_image=IMG_LoadJPG_RW(rwop);
      if(!loaded_image) {
        printf("Faild to load Image: '%s'. IMG_LoadJPG_RW returned Error: %s\n", imgpath, IMG_GetError() );
        return NULL;
      }
      //Create an optimized image 
      result = SDL_DisplayFormat( loaded_image );
      SDL_FreeSurface(loaded_image);
      SDL_FreeRW(rwop);
      return result;
    }
    und es so aufrufen:
    splash = loadJPG("../gfx/sdl.jpg" );
    
    if(splash != NULL)
    {
      ...
    }


    Edit: Habe SDL_FreeRW() und SDL_FreeSurface() hinzugefügt wegen Memory-Leak.


  • in: linux shell script ebook kostenlos

    geschrieben von darkpandemic

    Hallo hpage,

    das Standardwerk zum Thema ist:
    Advanced Bash-Scripting Guide
    Es gibt davon auch eine PDF-Version, vielleicht geht das ja als E-Book durch:
    http://tldp.org/LDP/abs/abs-guide.pdf
  • in: Funktionen die AD Abfragen in VBA (Excel) vereinfachen...

    geschrieben von darkpandemic

    Hallo timebase,

    hast Du mal versucht den 'OU=Benutzer'-Teil einfach wegzulassen?

    Edit: Welche Bedeutung hat eigentlich die geschlossene runde Klammer nach 'OU=Benutzer'?
  • in: Guter Texteditor

    geschrieben von darkpandemic

    PSPad ist ein kostenloser Nachbau von UltraEdit. Der ist auf jedenfall auch einen Blick wert:
    http://www.pspad.com/de/

Login zum Webhosting ohne Werbung!