Autor Beitrag
Killi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Fr 24.10.03 15:12 
Hi!

Es geht um folgendes problem: Ich lese eine Krankenkassenkarte mit TSmartCard aus, Beispiel-Code war dabei, damit kann ich nix anfangen, habe es eben drin gelassen - Daten werden auch wunderbar gelesen, allerdings gibt es auch Karten auf denen der Name mit Umlauten, also ä,ö und üs geschrieben wird - hier bekomme ich nur ein "{"...wie kann ich das verhindern? Liegt es etwa daran (?):
ausblenden volle Höhe Delphi-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:
procedure TFKarte.ExecSCardCmd(Cmd,DataIn: String);
const BufferSize = 32768;
var P,pDataIn: PChar;
    DataASCII, DataHex, DataInHex: String;
    C: Integer;
    Len, LenIn: LongInt;
begin
  MemoDataOut.Clear;
  if (Cmd = ''then begin
    MemoDataOut.Lines.Add('no command');
    exit;
  end;
  with EditDataIn do if ((Font.Color=clRed) and (Text='(nil)')) then DataIn:='';
  ShowCommand(Cmd,DataIn);
  P:=AllocMem(BufferSize);
  if DataIn='' then begin pDataIn:=nil; LenIn:=0end else begin
    if RadioButtonHEX.Checked then begin
      (* DataIn can either be in ASCII or in HEX, depending on the
         seleced RadioButton. If we have a HEX string (e.g. for
         "Card,APDU", see function ButtonAPDUClick below), we have
         to convert the HEX values to the real characters *)

      DataInHex:=HexStrToTxt(DataIn);
      EditDataIn.Text := TxtToHexStr(DataInHex);
      LenIn := Length(DataInHex);
      pDataIn:=@DataInHex[1];
    end else begin
      (* if RadioButtonASCII is selecte, we can use DataIn directly *)
      LenIn := Length(DataIn);
      pDataIn:=@DataIn[1];
    end;
  end;


  (* If Cmd is an invalid command, the SCardServer will create a message box
     which must be confirmed. After confirmation the program will continue
     and the component raises an ESmartCard exception.
     So, if this is the only line in the Memo field, please check for any
     message box from the SCardServer. This can happen during your development
     phase, but your final release should never use any invalid commands! *)

  try

    (* now we execute the command, Len returns the length of the data in P. *)
    Len:=SmartCard.Comand(Cmd,pDataIn,LenIn,P,BufferSize);
    (* The component throws an exception if an error occurs. Here
       we don't do any detailed error handling, but our try-finally
       block take care that at least the buffer p is freed again *)


    if Len <> 0 then begin
      (* Show DataOut in HEX *)

      (* and now show DataOut in ASCII, non printable characters become "°" *)

      DataASCII:='';
      for C:=0 to Len-1 do begin
        case P[C] of
        #0..#31: DataASCII:=DataASCII+'°';
          else DataASCII:=DataASCII+P[C];
        end;
      end;
      if DataASCII <> '' then begin
        MemoDataOut.Lines.Add(DataASCII);
      end;
    end;
  except
    on E:ESmartCard do begin (* the componen creates this exception *)
      MemoDataOut.Lines.Add(' ');
      MemoDataOut.Lines.Add('SmartcardException: '+E.Message);
    end;
    on E:Exception do begin (* we'd better catch all exceptions here *)
      MemoDataOut.Lines.Add(' ');
      MemoDataOut.Lines.Add('Exception: '+E.Message);
    end;
  end;
  FreeMem(P,BufferSize);
end;


Hoffe ihr könnt mir helfen....
Wolff68
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 302
Erhaltene Danke: 1

WinXP home
D6 Prof
BeitragVerfasst: Fr 24.10.03 18:35 
Generell könnte es an der verwendeten Schriftart liegen, da ASCII-Codes über 128 nicht "genormt" sind.
Ebenso kann es sein, daß aus Speicherplatzgründen die Zeichen auf der Karte in nur 4 Bits gespeichert werden (Also nur ASCII 0-128 zulässt)
So könnte zB aus einem ü eine { werden... (oder hab ich mich jetzt verrechnet?)

Du könntest aber mal nachsehen, welche ASCII-Codes Du von der Karte überhaupt bekommst.
Ä= 196
Ö= 214
Ü= 220
ä= 228
ö= 246
ü= 252
ß= 223

{= 123

_________________
"Der Mensch ist nicht was er sich vorstellt oder wünscht zu sein, sondern das was andere in ihm sehen."
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 24.10.03 19:22 
Ich glaube nicht, dass die Zeichen nur mit 4 Bits codiert sind. Wie willst du sonst Müller von Mueller unterscheiden? Soll es nämlich auch geben.
Killi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Mi 29.10.03 10:06 
Hi!

Die Theorie von Wolff68 könnte stimmen, da ich die Umlaute etc. schon als ~ zurückbekomme - und meine LÖSUNG für das Problem stimmt auch, ich ersetzte #225 durch ß, dann kommt die Straße richtig - allerdings werden ja äs, ös und üs auch mit einem ~ gekennzeichnet - und hie ist mein Problem, es kommen anscheinend keine Datensätze über #128 an...d.h. ich bekomme immer nur ein ~ schon im ASCII-Code.....
Kann das am Treiber liegen??? Weil das kartenlesegerät müsste es können...von der Firma gibts auch eine Krankenkassenlösung die das kann....ich versteh gar nix mehr!
Maggi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 160

WIN XP, WIN 2003
D5 Enter D 2006
BeitragVerfasst: Mi 29.10.03 14:11 
Hi,

kann es sein das du ineinem ganz anderen Zeichensatz unterwegs bist.

OEM oder so, dann mußt du erst konvertieren und alles wird gut. Wird auch in der Hilfe sehr gut beschrieben!

Gruß

Maggi

_________________
"Wir haben den Kontakt zur Realität verloren, aber die findet uns schon wieder"
Killi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Mi 29.10.03 14:37 
OEM Zeichensatz sagt mir leider nix, hab keine Ahnung wie die Daten codiert sind - guck dir oben mal meinen Code an, is rauskopiert - das macht den ganzen sch...! Aber da steht nur was von ASCII zu norml. Text!?
Also...!!??
Killi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Do 30.10.03 12:01 
kann mir keiner mehr helfen? :(
Spieler1
ontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 469


D6 Pers
BeitragVerfasst: Do 30.10.03 23:57 
Das geht schon, du musst nur ein unsigned char verwenden, da sind dann auch solche Sonderzeichen drin.
Killi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Fr 31.10.03 10:13 
unsigned??? Wie mach ich das? Kann ja fast nix mit der Prozedur anfangen...kannst du mir helfen?
Ja-Pa
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 458

Win XP, Suse 9.3
D1, D3, D5 Std, D7 Pro, D2005 Pers, Kylix 3
BeitragVerfasst: Fr 31.10.03 13:46 
Maggi hat folgendes geschrieben:

OEM oder so, dann mußt du erst konvertieren und alles wird gut.


Dieses Problem habe ich auch, wenn ich ActiveX-Controls einen String übergeben will.
Der hängt sich bei Sonderzeichen dann auf.
Vielleicht muss ich das auch konvertieren?
Wie mache ich das?

Gruß, Ja-Pa

_________________
Der Autor dieses Textes haftet nicht für Schäden an Soft- oder Hardware
oder Vermögensschäden, die durch das Benutzen des Textes entstehen.
Spieler1
ontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 469


D6 Pers
BeitragVerfasst: Fr 31.10.03 13:49 
Sorry, hab vergessen, dass das ein Delphi Forum ist und ich kein Delphi kann.
Den Typ unsigned char gibt es in C/C++, da kann man einfach schreiben:
ausblenden Quelltext
1:
unsigned char meinString[100];					

Dann hat man einen String, in dem 255 (glaub ich) verschiedene Zeichen vorkommen können, ein normaler char hat nur die Hälfte. Vielleicht hilft dir das ja auch bei Delphi irgendwie :? .
:D
Maggi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 160

WIN XP, WIN 2003
D5 Enter D 2006
BeitragVerfasst: Fr 31.10.03 13:52 
Hi,

Schau doch mal in der Hilfe unter "OemToAnsi" nach in der Gegend findest du einige Fkt die dir vielleicht weiter helfen!! :lol:

Gruß

Maggi

_________________
"Wir haben den Kontakt zur Realität verloren, aber die findet uns schon wieder"
Killi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Mo 03.11.03 12:19 
Das bringt mich doch alles nicht weiter, ich weiß genau dass ich die Daten in ASCII bekomme...ist etwas an der ASCII-Funktion falsch? Bekomme ja keinen Wert wie 255 oder so....weiß nicht mehr weiter!!!
Brueggendiek
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 304

Win 98, Win98SE, Win XP Home
D5 Std
BeitragVerfasst: Mo 03.11.03 23:47 
Hallo Killi!

Nach der beliebten Winzig-Weich-Methode "Halte Dich nie an bestehende Standards, was WinzigWeich sagt, ist der neue Standard" hat der große Billy-Boy-Gates-jetzt-endlich beschlossen, daß Windows nicht mit dem ASCII-Code, sondern mit dem ANSI-Code arbeitet. Damit ist per WinzigWeicher Verfügung der bisherige Standard ASCII ungültig.

ASCII ist im Original ein 7-Bit-Code. Früher wurde bei Modem-Übertragung oft noch ein Paritätsbit verwendet, man übertrug 7 Bit + Parität, also 8 Bit zusammen.
Inzwischen gibt es einen ASCII-Standard, der mit 8 Bit arbeitet und damit auch so schöne Dinge wie Umlaute und Rahmengrafik (Blockgrafik) enthält.

Der ANSI-Code von Windows entspricht in den ersten 128 Zeichen dem ASCII-Code (7-Bit-Code). Die Zeichen ab $80 werden jedoch komplett anders belegt und sind somit nicht kompatibel zu ASCII. Insbesonders fehlen die Blockgrafikzeichen.

Bei Windows wird der ASCII-Zeichensatz als OEM-Zeichensatz bezeichnet. Damit sollte die Funktion "OEMtoANSI" einen ASCII-String - soweit die Zeichen definiert sind - in den Windows-Zeichensatz umwandeln.

Wenn Du Sicher bist, daß es ASCII ist, sollte die genannnte Funktion helfen. Wenn nicht, hilft nur das Ausprobieren, d.h. Karten mit Umlauten in den Namen organisieren und nachsehen, was da kommt. Dann mit Stringreplace oder durch zeichenweises Bearbeiten eine eigene Umwandlung realisieren.

Gruß

Dietmar Brüggendiek
Killi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Di 04.11.03 11:50 
Danke für die klärende Antwort!
Strreplace hätt ich schon lange gemacht, (bin ja faul) aber das geht eben nicht, da lles als "}" angezeigt wird, ist ja die sch...! Gut, ich teste es mal mit OEMToANSI!
Killi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Di 04.11.03 12:26 
Titel: hm...
...hier der neue Code, vielleicht hab ichs ja auch falsch eingebunden, OEMtoANSI steht jetzt VOR der "normalen" Textausgabe, aber es tut sich gar nix:

ausblenden volle Höhe Delphi-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:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
procedure TFormMain.ExecSCardCmd(Cmd,DataIn: String);
const BufferSize = 32768;
var P,pDataIn: PChar;
    DataASCII, DataHex, DataInHex: String;
    C: Integer;
    Len, LenIn: LongInt;
begin
  MemoDataOut.Clear;
  if (Cmd = ''then begin
    MemoDataOut.Lines.Add('no command');
    exit;
  end;
  with EditDataIn do if ((Font.Color=clRed) and (Text='(nil)')) then DataIn:='';
  ShowCommand(Cmd,DataIn);
  P:=AllocMem(BufferSize);
  if DataIn='' then begin pDataIn:=nil; LenIn:=0end else begin
    if RadioButtonHEX.Checked then begin
      (* DataIn can either be in ASCII or in HEX, depending on the
         seleced RadioButton. If we have a HEX string (e.g. for
         "Card,APDU", see function ButtonAPDUClick below), we have
         to convert the HEX values to the real characters *)

      DataInHex:=HexStrToTxt(DataIn);
      EditDataIn.Text := TxtToHexStr(DataInHex);
      LenIn := Length(DataInHex);
      pDataIn:=@DataInHex[1];
    end else begin
      (* if RadioButtonASCII is selecte, we can use DataIn directly *)
      LenIn := Length(DataIn);
      pDataIn:=@DataIn[1];
    end;
  end;


  MemoDataOut.Lines.Add('executing command....');
  (* If Cmd is an invalid command, the SCardServer will create a message box
     which must be confirmed. After confirmation the program will continue
     and the component raises an ESmartCard exception.
     So, if this is the only line in the Memo field, please check for any
     message box from the SCardServer. This can happen during your development
     phase, but your final release should never use any invalid commands! *)

  try

    (* now we execute the command, Len returns the length of the data in P. *)
    Len:=SmartCard.Comand(Cmd,pDataIn,LenIn,P,BufferSize);
    (* The component throws an exception if an error occurs. Here
       we don't do any detailed error handling, but our try-finally
       block take care that at least the buffer p is freed again *)


    if Len = 0 then begin
      MemoDataOut.Lines.Add('command successful');
      (* in at least a message to tell the user that everything is ok *)
    end else begin
      (* Show DataOut in HEX *)
      MemoDataOut.Font.Name:='Courier';
      MemoDataOut.Font.Style:=[];
      MemoDataOut.Lines.Add('DataOut in HEX:');
      MemoDataOut.Lines.Add(' ');
      DataHEX:='';
      for C:=0 to Len-1 do begin
        DataHEX:=DataHEX+IntToHex(Ord(P[C]),2)+' ';
        if (Length(DataHex)=48then begin
          DataHEX:=DataHEX+' ['+IntToStrEx(C,3)+']';
          MemoDataOut.Lines.Add(DataHEX);
          DataHEX:='';
        end;
      end;
      if DataHEX <> '' then begin
        while Length(DataHEX)<49 do DataHEX:=DataHEX+' ';
        DataHEX:=DataHEX+'['+IntToStrEx(C,3)+']';
        MemoDataOut.Lines.Add(DataHex);
      end;
      (* and now show DataOut in ASCII, non printable characters become "°" *)
      MemoDataOut.Lines.Add(' ');
      MemoDataOut.Lines.Add('DataOut in ASCII:');
      MemoDataOut.Lines.Add(' ');
      DataASCII:='';

      OEMtoAnsi(P, P); // <-- HIER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

      for C:=0 to Len-1 do begin
        case P[C] of
          #0..#31: DataASCII:=DataASCII+'°';

      //    #132: DataASCII:=DataASCII+'ä';
      //    #142: DataASCII:=DataASCII+'Ä';
      //    #129: DataASCII:=DataASCII+'ü';
      //    #154: DataASCII:=DataASCII+'Ü';
      //    #148: DataASCII:=DataASCII+'ö';
      //    #153: DataASCII:=DataASCII+'Ö';
      //    #225: DataASCII:=DataASCII+'ß';
          else DataASCII:=DataASCII+P[C];
        end;
        if ((Length(DataASCII)>32or (P[C]=#13)) then begin
          if (P[C]=#13then begin (* after a <CR>, we start a new line *)
            while Length(DataASCII)<37 do DataASCII:=DataASCII+' ';
            DataASCII:=DataASCII+'(#13 found) ';
          end else while Length(DataASCII)<49 do DataASCII:=DataASCII+' ';
          MemoDataOut.Lines.Add(DataASCII+'['+IntToStrEx(C,3)+']');
          DataASCII:='';
        end;
      end;
      if DataASCII <> '' then begin
        while Length(DataASCII)<49 do DataASCII:=DataASCII+' ';
        MemoDataOut.Lines.Add(DataASCII+'['+IntToStrEx(C,3)+']');
      end;
    end;
  except
    on E:ESmartCard do begin (* the componen creates this exception *)
      MemoDataOut.Lines.Add(' ');
      MemoDataOut.Lines.Add('SmartcardException: '+E.Message);
    end;
    on E:Exception do begin (* we'd better catch all exceptions here *)
      MemoDataOut.Lines.Add(' ');
      MemoDataOut.Lines.Add('Exception: '+E.Message);
    end;
  end;
  FreeMem(P,BufferSize);
end;



Moderiert von user profile icontommie-lie: Code- durch Delphi-Tags ersetzt

_________________
----
Life is hard and then you die
elysm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25


D6 Enter, D6 Pers, D7 Pro
BeitragVerfasst: Mi 05.11.03 10:58 
Zitat:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
      for C:=0 to Len-1 do begin 
        case P[C] of 
          #0..#31: DataASCII:=DataASCII+'°'; 

      //    #132: DataASCII:=DataASCII+'ä'; 
      //    #142: DataASCII:=DataASCII+'Ä'; 
      //    #129: DataASCII:=DataASCII+'ü'; 
      //    #154: DataASCII:=DataASCII+'Ü'; 
      //    #148: DataASCII:=DataASCII+'ö'; 
      //    #153: DataASCII:=DataASCII+'Ö'; 
      //    #225: DataASCII:=DataASCII+'ß'; 
          else DataASCII:=DataASCII+P[C];

nimm doch einfach mal die slash´s vor den angaben weg!! das wäre das erste gewesen was ich gemacht hätte!
es sei den du hast die dahin gemacht.. denn hab ich nix gesagt! ;)
Killi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 299

Win*
D6 Prof
BeitragVerfasst: Mi 05.11.03 11:37 
die hab ich dahin gemacht weils nix bringt......das is ja die scheibenwischanlage

_________________
----
Life is hard and then you die