Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

21

16.02.2008, 17:13

Also, ich fass das mal schnell zusammen:

Der Unicodestandard wurde entworfen um ein größeres Spektrum an Schriftzeichen am Computer verarbeiten zu können, und zwar mit einer einheitlichen Indizierung für jeden Glyphen. (Ohne z.B. Codepages austauschen zu müssen).
Es hat also mitnichten nur etwas mit "Sonderzeichen" zu tun, sondern wird, mittlerweilen, algemein zur Verarbeitung und Darstellung von Zeichen verwendet.

In vergangenen Zeiten gab es immer wieder Ansätze das Zeichenspektrum zu erweitern (selbst die englischsprachigen Länder mussten irgendwann zugeben das die 127 Zeichen des ASCII zu wenig waren). Darunter war z.B. ein erweiterter ASCII Zeichensatz, diverse Ansätze mit austauschbaren Codepages uswusf. Seit Windows 98SE unterstüzt Windows aber (immer mehr) auch Unicode.

Um rückwärtskompatibel zu bleiben bietet die Windows API (kurz WinAPI) für viele Funktionen zwei Typen an. Einmal den alten Typ für ANSI und einmal den neuen, der Unicode verwendet.
Die Namen der Funktionen enden, je nach Typ, mit einem A (Ansi) oder einen W (Widechar).

Zum Beispiel ist die Funktion MessageBoxW der Unicodeequivalent zur Funktion MessageBoxA. Um dies zu vereinheitlichen wurden Makros eingeführt hinter denen sich, je nach eingestellungen, entweder die Ansi oder die Unicodevariante der jeweiligen Funtkionen steckt.

Zum Beispiel:

#if defined( _UNICODE ) // Wenn Unicode verwendet wird
#define MessageBox MessageBoxW
#else // ansonsten
#define MessageBox MessageBoxA
#endif

Wenn man also die Funktion MessageBox im Code verwendet, macht der Präprozessor entsprechend ein MessageBoxW oder MessageBoxA daraus.

Nun werden Unicodezeichen etwas anders im speicher repräsentiert als Ansizeichen. Für Ansi reichte die "Bandbreite" von 8 Bit aus (bei Windows entspricht das einem Byte = char). Unicode bietet aber mehr Platz für mehr Zeichen, deshalb benötigt ein Unicodezeichen 32 Bit (= 4 Byte). Um die Platzverschwendung möglichst gering zu halten (nicht alle Zeichen nutzen schließlich die 32 Bit eines Unicodecharakters) wurden diverse Techniken entwickelt die den Speicherverbrauch senken (UTF-8, UTF-16). Windows nutzt letzteres Codierungsverfahren und benötigt deshalb für einen Codepoint (=ein Unicodezeichen) mindestens 16 Bit.

Aus diesem Grund musste ein anderer Datentyp her um Zeichenketten zu repräsentieren, nämlich wchar_t. Dieser Typ bietet under Windows32 genau die 16 Bit die benötigt werden und dieser Datentyp wird von den Unicodevarianten der WindowsAPI Funktionen erwartet.

Nun erwartet auch MessageBoxW den Typ wchar_t für die Textparameter. Deshalb kann der Code mit der übergabe von const char* auch nicht compiliert werden, weil der übergebene Typ schlichtweg falsch ist.

Anmerkung: LPCWSTR ist eine WinAPI eigene Definition für const wchar_t* (LongPointerConstWideSTRing).

Was tun sprach also Gates... (rein bildlich gesehen). Und es wurde eine weitere Definition eingeführt, die sich, abhängig vom verwendeten Zeichensatz, dynamisch anpasst:

#if defined( _UNICODE )
#define TCHAR wchar_t
#else
#define TCHAR char
#endif

Verwendet man also TCHAR (statt char oder wchar_t) so hat man immer den richtigen Datentyp für Zeichen bei der Hand! :)

grüße
@D13_Dreinig

22

16.02.2008, 17:40

Amen!
Und Respekt! Hast du dir 'ne Mühe gemacht.
Wer jetzt noch irgendwie rumnöhlt wird mit Musikantenstadl nicht unter vier Wochen besstraft!

Terep

Frischling

  • »Terep« ist der Autor dieses Themas

Beiträge: 46

Wohnort: Region Hannover

  • Private Nachricht senden

23

16.02.2008, 17:55

Entschuldigung, dass ich so gedrängt habe.

Jetzt habe ich es kapiert:
Der Standard für die Verarbeitung von Zeichen hat sich geändert. Daher hat das Visualstudio bei dem Hochladen des Quellcodes automatisch konvertiert. Daher ging es.

Den Quellcode, den ich abgetippt habe, muss dahingehend aktualisiert werden, wie David_pb es in seiner ersten Kurzantwort beschrieben hat:
const char szClassName[] = "Erstes Fenster";
ändern in
const TCHAR szClassName[] = "Erstes Fenster";

Anschließend ändere ich noch wie TrikkieMikkie es postet:

Projekt - Eigenschaften - Konfigurationseigenschaften - Allgemein - Zeichensatz -> Unicode-Zeichensatz verwenden

auf

Projekt - Eigenschaften - Konfigurationseigenschaften - Allgemein - Zeichensatz -> Nicht festgelegt.

Damit habe ich sozusagen von Hand konvertiert.

Und es funktioniert; genial das Gefühl es zu verstehen.

Für mich hat es sich wirklich gelohnt nachzuhaken.
Danke für die Zeit, die Ihr aufgewendet habt.

Terep :D

PS: Macht es Sinn, die Projekteigenschaften allgemein auf „Nicht festgelegt“ zu setzen ?

PPS: Ich denke TrikkieMikkie hat mit seinem letzten Posting recht. Die Antwort war wirklich gut.
Avatar = „Odyssee im Weltraum“
Film von Stanley Kubrick (Warner Brothers)
nach dem Buch von Arthur C. Clarke.
It will becoming true ?!!

Das Gurke

Community-Fossil

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

24

16.02.2008, 17:58

Nein, du hast es leider nicht begriffen. Jetzt, wo du Unicode abgeschaltet hast geht zwar alles, du hast damit aber auch deinen ersten Schritt überflüssig gemacht ;)

Wenn du *bewusst* auf Unicode verzichten möchtest, kannst du weiterhin mit char* arbeiten. Wenn du dir Unicode doch noch freihalten möchtest, arbeitest du mit TCHAR und TEXT() (und stellst den Zeichensatz wieder um).

Terep

Frischling

  • »Terep« ist der Autor dieses Themas

Beiträge: 46

Wohnort: Region Hannover

  • Private Nachricht senden

25

16.02.2008, 18:11

Das Gurke, Du hast recht

Die Einstellung auf „nicht festgelegt“ genügt schon um die Fehlermeldungen zu vermeiden.
Bis sich das ganze Drumherum bei mir gesetzt hat, werde ich wohl diese Einstellung „nicht festgelegt“ setzen.

Bin doch froh, überhaupt da zu sein, sprich mit dem Buch weitermachen zu können. Der Umstieg von der Konsole ist für mich schwer genug und ich werde wohl noch eine ganze Zeit brauchen, um inhaltlich mitreden zu können.
Sei bitte nicht sauer, dass ich es vorher nicht kapiert habe!

Terep :)
Avatar = „Odyssee im Weltraum“
Film von Stanley Kubrick (Warner Brothers)
nach dem Buch von Arthur C. Clarke.
It will becoming true ?!!

Das Gurke

Community-Fossil

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

26

16.02.2008, 18:39

Böse bin ich ganz bestimmt nicht ;)

Unicode ist nur eins dieser Themen, vor denen viele unbegründet Angst haben. Für den Anfang braucht man wirklich nicht mehr als das TCHAR Makro und das TEXT Makro. Und muss dann nicht auf die Möglichkeiten von Unicode (ä,ö,ü,ß) verzichten. Es ist *NICHT* schwierig ;)

Du schreibst in Zukunft eben nur:

C-/C++-Quelltext

1
TCHAR classname[] = TEXT("Klassenname");
statt

C-/C++-Quelltext

1
char classname[] = "Klassenname";


Und die Winapi macht den Rest für dich ;)

Nelrim

Frischling

Beiträge: 33

Beruf: Entwicklungskonstrukteur

  • Private Nachricht senden

27

24.02.2008, 02:30

Zitat von »"Das Gurke"«

Böse bin ich ganz bestimmt nicht ;)

Unicode ist nur eins dieser Themen, vor denen viele unbegründet Angst haben. Für den Anfang braucht man wirklich nicht mehr als das TCHAR Makro und das TEXT Makro. Und muss dann nicht auf die Möglichkeiten von Unicode (ä,ö,ü,ß) verzichten. Es ist *NICHT* schwierig ;)

Du schreibst in Zukunft eben nur:

C-/C++-Quelltext

1
TCHAR classname[] = TEXT("Klassenname");
statt

C-/C++-Quelltext

1
char classname[] = "Klassenname";


Und die Winapi macht den Rest für dich ;)


also da ich jetzt mal auch im Buch weitergemacht habe bin ich logischerweise ins gleiche Verderben gerannt wie die Schreiber vor mir...

Was ich jetzt nach lesen deines letzten Postings nicht verstehe:

So wie du schreibst klingt das so als könne man nach Umstellung auf "nicht festgelegt" keine ÖÖÖ ÄÄ und so benutzen...

Zitat von »"Das Gurke"«


Für den Anfang braucht man wirklich nicht mehr als das TCHAR Makro und das TEXT Makro. Und muss dann nicht auf die Möglichkeiten von Unicode (ä,ö,ü,ß) verzichten. Es ist *NICHT* schwierig ;)


ich hab beides ausprobiert (das umstellen und das mit TCHAR... beides funktioniert und in beiden Varianten hatte mein Fenster den schönen Namen ÖÖÖÖÖÖÄÄÄÄÄHM... (C) ich hab keinen Unterschied gesehen.

Was genau meinst du damit man verzichtet auf irgendwas wenn man auf "nicht festgelegt" umstellt?

danke schonmal

Nelrim
Auch der längste Weg beginnt mit einem ersten Schritt.

NicoWe

Treue Seele

Beiträge: 126

Wohnort: Bielefeld / NRW

  • Private Nachricht senden

28

24.02.2008, 09:13

http://unicode.e-workers.de/unicode.php
Erfolg ist die Fähigkeit, von einem Misserfolg zum anderen zu gehen,
ohne seine Begeisterung zu verlieren.
-Winston Churchill-

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

29

24.02.2008, 09:18

Zitat von »"NicoWe"«

http://unicode.e-workers.de/unicode.php


Was willst du uns jetzt mit den HTML Codes für Unicodezeichen mitteilen?
@D13_Dreinig

Zeus

Frischling

Beiträge: 83

Beruf: Schule

  • Private Nachricht senden

30

11.05.2008, 21:30

so, schließe mich hier mal mit problemen an, hab das bsp mitels der faq zum laufen gebracht

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# include <windows.h>

LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); //callback


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpcmdline, int ncmdshow){
    
    WNDCLASSEX  windowclass;
    HWND        hWnd;
    MSG         message;

    const TCHAR szClassName[] = TEXT("Das erste Fenster");

    windowclass.cbSize = sizeof(WNDCLASSEX);        //zwischensp. größe struct


    windowclass.style = CS_HREDRAW | CS_VREDRAW;    //neuzeichnen des feinsters bei verschiebung


    windowclass.lpfnWndProc = WindowProc;           // pointer @ callback


    windowclass.cbClsExtra = 0;
    windowclass.cbClsExtra = 0;

    windowclass.hIcon   = LoadIcon(NULL, IDI_APPLICATION);
    windowclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    windowclass.hCursor = LoadCursor (NULL, IDC_ARROW);

    windowclass.hbrBackground = (HBRUSH) COLOR_BACKGROUND+1;

    windowclass.lpszMenuName = NULL;

    windowclass.lpszClassName = szClassName;

    if(!RegisterClassEx(&windowclass)) return 1;

    hWnd = CreateWindowEx ( NULL,
                            szClassName,
                            TEXT("Das erste Fenster!"),
                            WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                            100, 100,
                            300, 250,
                            NULL,
                            NULL,
                            hInst,
                            NULL);

    if(hWnd == NULL) return 2;

    while (GetMessage(&message, NULL, 0, 0))
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    return(int)(message.wParam);
}       //winmain


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 3;
        }
    case WM_KEYDOWN:
        {
            switch(wParam)
            {
            case VK_ESCAPE:
                {
                    PostQuitMessage(0);
                    return 4;
                }
            }
        } break;
    }

    return (DefWindowProc (hWnd, message, wParam, lParam));
}


beckomme jetz allerding folgende meldung

"test3.exe": "C:\Users\Zeus\Documents\Visual Studio 2008\Projects\test3\Debug\test3.exe" geladen, Symbole wurden geladen.
"test3.exe": "C:\Windows\SysWOW64\ntdll.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\kernel32.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\user32.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\gdi32.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\advapi32.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\rpcrt4.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\secur32.dll" wurde geladen
"test3.exe": "C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.21022.8_none_96748342450f6aa2\msvcr90d.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\imm32.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\msctf.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\msvcrt.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\lpk.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\usp10.dll" wurde geladen
"test3.exe": "C:\Program Files (x86)\Kaspersky Lab\Kaspersky Internet Security 7.0\r3hook.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\psapi.dll" wurde geladen
"test3.exe": "C:\Windows\SysWOW64\shlwapi.dll" wurde geladen
"test3.exe": "C:\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.6001.18000_none_5cdbaa5a083979cc\comctl32.dll" wurde geladen
"test3.exe": "C:\Program Files (x86)\Kaspersky Lab\Kaspersky Internet Security 7.0\adialhk.dll" wurde geladen
"test3.exe": "C:\Program Files (x86)\Kaspersky Lab\Kaspersky Internet Security 7.0\adialhk.dll" entladen.
Das Programm "[2848] test3.exe: Systemeigen" wurde mit Code 1 (0x1) beendet.

und wollte wissen ob wer weis wieso sich das ding nicht registered beckommt ...

(win vista64, kaspersky internet security 7)

mfg

Werbeanzeige