怎么我用这一个函数会出现乱码?是海康压缩卡的SDK[ds40xxsdk.dll]
官方的SDK是
=========================================================================
4.42 SetOsdDisplayMode(HANDLE hChannelHandle, int Brightness, BOOL Translucent, int TwinkleInterval, USHORT *Format1, USHORT *Format2)
参数:HANDLE hChannelHandle 通道句柄
int Brightness OSD显示亮度,255最亮,0最暗;
BOOL Translucent OSD图象是否做半透明处理;
Int TwinkleInterval (V3.2改动为:当值为1时,OSD的亮度根据背景的亮度来调整,但背景较亮时,OSD亮度自动调低,但背景较暗时,OSD亮度自动调亮。原来的闪烁功能关闭)3.2版本之前请参考4.41节描述。
USHORT *Forma1,* Format2 描述字符叠加的位置和次序的格式
串,具体定义如下:
USHORT X, USHORT Y, CHAR0, CHAR1, CHAR2,… CHARN, NULL
其中X,Y 是该字串在标准CIF图象的起始位置,X必须是8的倍数,Y可以在图象高度内取值即(0-287)PAL 、(0-239)NTSC;CHARN也是USHORT型的参数,可以是ASCII码也可以是汉字,当想要显示当前时间时,可以指定为固定的时间定义值,其值如下:
_OSD_YEAR4 四位的年显示,如2002
_OSD_YEAR2 两位的年显示,如02
_OSD_MONTH3 英文的月显示,如 Jan
_OSD_MONTH2 两位阿拉伯数字的月显示,如07
_OSD_DAY 两位的阿拉伯数字的日显示,如31
_OSD_WEEK3 英文的星期显示,如Tue
_OSD_CWEEK1 中文的星期显示,如星期二
_OSD_HOUR24 24小时的时钟显示,如18
_OSD_HOUR12 12小时的时钟显示,如AM09或PM09
_OSD_MINUTE 两位分钟的显示
_OSD_SECOND 两位秒的显示
在格式字符串的最后必须以NULL(0)结尾,否则会显示错误的内容。
字符串和时间显示可以在FORMAT1 也可以在FORAMT2,也可以混合在一起,但不得超过一行CIF 图象的宽度。
要显示位置在16,19的字符串“办公室”的格式字符串如下:
USHORT Format[] = {16, 19, ‘办’,’公’,’室’, ‘\0’};
要显示位置在8, 3的时间字符串可以如下:
USHORT Format[]={8, 3, _OSD_YEAR4, ‘年’,_OSD_MONTH2,’月’,_OSD_DAY, ‘日’,_OSD_HOUR24,’:’, _OSD_MINUTE, ‘:’, _OSD_SECOND, ‘\0’};
DS-400xH 系列 SDK 说明书 13
海康威视技术文档(版权所有)
如果只想显示其中一行,则将起始的字符串定义如下:
USHORT FormatNoDisplay[]={0, 0, ‘\0’};
==========================================================================================
下面是我调用的
引用:
==========================================================================================
function SetOsdDisplayMode(hChannelHandle:integer;Brightness:integer;Translucent:bool;param:integer;Format1,format2:pointer):integer;stdcall;
==========================================================================================
var
  Format1,Format2:array[0..40] of Word ;
  _OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:word;
begin
  Format1[0]:=0;
  Format1[1]:=0;
  Format1[2]:= Ord(' ') ;
  Format1[3]:= _OSD_YEAR4;
  Format1[4]:= Ord('-') ;
  Format1[5]:= _OSD_MONTH2;
  Format1[6]:= Ord('-') ;
  Format1[7]:= _OSD_DAY;
  Format1[8]:= Ord(#0) ;  Format2[0]:= Ord(#0) ;
  SetOsdDisplayMode(0,255, false,1, @Format1, @Format2);
  setosd(0,true);  //这个是启动的
end;
==========================================================================================

解决方案 »

  1.   

    SetOsdDisplayMode(0,255, false,1, @Format1, @Format2); 
    是一启动这一个函数的时候就显示乱码,是不是接口有调用问题
      

  2.   

    SetOsdDisplayMode(0, 255, false, 1, Format1, Format2)
    Format1, Format2 表示数组的首地址;
    看下给你的文档里的这个函数说明
      

  3.   

    想必是与\0有关系,更改如下:
      Format1[8]:= Ord(#0) ;
      Format1[9]:= #0 ;
      Format2[0]:= Ord(#0) ; 
      Format2[1]:= #0 ; 
      

  4.   

    Format2[1]:= #0 ; [DCC Error] Unit1.pas(125): E2010 Incompatible types: 'Word' and 'Char'
      

  5.   

    word和char不匹配转换一下看看
      

  6.   

    var 
      Format1,Format2:array[0..40] of Word ; 
      _OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:word; 
    begin 
      Format1[0]:=0; 
      Format1[1]:=0; 
      Format1[2]:= Ord(' ') ; 
      Format1[3]:= _OSD_YEAR4; 
      Format1[4]:= Ord('-') ; 
      Format1[5]:= _OSD_MONTH2; 
      Format1[6]:= Ord('-') ; 
      Format1[7]:= _OSD_DAY; 
      Format1[8]:= ord('\'); 
      Format1[9]:= Ord('0') ;   Format2[0]:= Ord('\'); 
      Format2[1]:= Ord('0');

      SetOsdDisplayMode(0,255, false,1, @Format1, @Format2); 
      setosd(0,true);  //这个是启动的 
    end; 
      

  7.   

    1、0終止符 應該要放在一起 '\0' 不能分開;
    2、關于ushort,從說明看這是c#中的類型,16位,兩個字節。由于dot net的類型為對象,值可以是字符串。
    3、你在delphi中,應該自己定義兩個字節的char類型,以符合要求
      

  8.   

    你可以这样定义
    format1,format: array [0..40] of string[2];
      

  9.   

      Format1[0]:=0; 
      Format1[1]:=0; 
      Format1[2]:= Ord('A') ; 
      Format1[3]:= Ord('B') ; 
      Format1[4]:= Ord('C') ; 
      Format1[5]:= Ord(#0) ; 像这样定义可以正常输出,但是一加_OSD_YEAR4就输出乱码了 
      

  10.   

    这个说明文档写的也够差的了,从例子推断,_OSD_YEAR4之类是要你自己转成字符的,而不是直接传整数
    另外,对Format参数换种声明可以变成这样,使用方便些:
    TMyFormat = packed record
    case X: Word of
      1 : ( Y: Word; );
      2 : ( _: Byte; Text : string[255]);
    end;
      procedure SetOsdDisplayMode(hChannelHandle: THanlde; Brightness: Integer; Translucent: Boolean; TwinkleInterval: Integer; const Format1, Format2: TMyFormat); //stdcall?;
    整个record的长度是259,用的时候最好先清0,然后先写Text,最后写y,比如
    var
      foo1, foo2 : TMyFormat;
    begin
      ...
      FillChar(foo2, SizeOf(foo2), 0);
      foo2.Text := Format(' %d-%.2d-%.2d', [year, month, day]);
      foo2.X := 0;
      foo2.Y := 0;
      SetOsdDisplayMode(..., foo1, foo2);
    end;
    原因是delphi的ShortString的第0个byte用来描述字符串长度,如果先给y赋值再写Text的话,会改变y的高位,定位就不对了
      

  11.   

    我前面说的不对,没仔细看,后面是按2字节寻址的而不是ANSI字符串,也不知道显示的字符集是gb2312还是unicode,后者还好办点儿,或者干脆写一个把字符串转成这个结构的比较方便……
      

  12.   

    _OSD_YEAR4 可能是被认为是 assii码,你把数组元素的长度增加且类型为char(象我上面定义的),以可以接收_OSD_YEAR4。
      

  13.   

    var
      Format1,Format2:array[0..40] of string[2];
    begin
      Format1[1]:='0';
      Format1[2]:= '\0';  Format2[0]:='16';
      Format2[1]:='16';
      Format2[2]:= 'A';
      Format2[3]:= 'A';
      Format2[4]:= 'B';
      Format2[5]:= '_OSD_YEAR4';
      Format2[6]:= '-';
      Format2[7]:= '_OSD_MONTH2';
      Format2[8]:= '-' ;
      Format2[9]:= '_OSD_DAY';
      Format2[10]:= '\0' ;
      SetOsdDisplayMode(1,255, true,1, @Format1, @Format2);
    end;
    =====================
    是不是像这样呢?
    还是不可以呀
      

  14.   


    var 
      Format1,Format2:array[0..40] of Word ; 
      _OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:word; 
    begin 
      Format1[0]:=0; 
      Format1[1]:=0; 
      Format1[2]:= Ord(' ') ; 
      Format1[3]:= _OSD_YEAR4; 
      Format1[4]:= Ord('-') ; 
      Format1[5]:= _OSD_MONTH2; 
      Format1[6]:= Ord('-') ; 
      Format1[7]:= _OSD_DAY; 
      Format1[8]:= Ord(#0) ;   Format2[0]:= Ord(#0) ; 
      SetOsdDisplayMode(0,255, false,1, @Format1, @Format2); 
      setosd(0,true);  //这个是启动的 
    end; 你都沒有給_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND初始化,指定值。
    _OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND:從文檔說明看,在它的dll中,應是代表代號。
    看能不能查到_OSD_YEAR4,_OSD_MONTH2,_OSD_DAY,_OSD_HOUR24,_OSD_MINUTE,_OSD_SECOND的相關信息
      

  15.   

    问题解决没?
    我刚刚看到,可以这样解决:
    dim format1() as integer
    dim format2() as integer
    dim x as integer   '想显示的坐标
    dim y as integer   '想显示的坐标
    dim m as integer
    dim strr1 as string
    dim strr2 as stringstrr1=chr(x)+chr(y)+"郑州净瓶高科有限公司songyunly"+chr(0)
    strr2=chr(x)+chr(y)+"2009-04-18 13:20:30""+chr(0)for m=1 to len(strr1)
        format1(m-1)=Cint(asc(right(left(strr1,m),1)))
    next m
    for m=1 to len(strr2)
        format2(m-1)=Cint(asc(right(left(strr1,m),1)))
    next m
    rs=SetOsdDisplayMode(0,255, false,1, Format1(0), Format2(0)); vb 语言写的抛砖引玉吧
      

  16.   

    我写的一段,参看一下Procedure TFrmMain.SetOSDFormat(ChannelNum: Integer); //设置视频OSD
    Var
      L, M, nLength: Integer;
      Format1, Format2: Array[0..40] Of Word;
      wFormat: Word;
      Str: String;
      wH, wL: Char;
    Begin
      L := 0;
      Format1[0] := 8;                      //X坐标
      Format1[1] := 22;                     //Y坐标
      Str := IntToStr(ChannelNum + 1);
      nLength := Length(Str);
      M := 1;
      While M < nLength + 1 Do
      Begin
        wH := Str[M];
        wL := Str[M + 1];
        If (Ord(wH) > 128) Then
        Begin
          M := M + 1;
          wFormat := Ord(wH) * 16 * 16 + Ord(wL);
        End
        Else
          wFormat := Ord(wH);
        Format1[L + 2] := wFormat;
        L := L + 1;
        M := M + 1;
      End;
      Format1[L + 2] := Ord(#0);
      //===============================================
      Format2[0] := 8;                      //X坐标
      Format2[1] := 5;                      //Y坐标
      Format2[2] := _OSD_YEAR4;
      Format2[3] := Ord('-');
      Format2[4] := _OSD_MONTH2;
      Format2[5] := Ord('-');
      Format2[6] := _OSD_DAY;
      Format2[7] := Ord(' ');
      Format2[8] := _OSD_HOUR24;
      Format2[9] := Ord(':');
      Format2[10] := _OSD_MINUTE;
      Format2[11] := Ord(':');
      Format2[12] := _OSD_SECOND;
      Format2[13] := Ord(#0);
      //===============================================
      HikVisionSDK.SetOsdDisplayMode(ChannelHandle[ChannelNum], 255, False, 0, @Format1, @Format2);
    End;
      

  17.   

    我这里有份他们给我的技术文档李工:
         你好!
         1.附件是我们内测Demo以及预览代码。
         2、关于Osd接口调用(主要部分),类似传参数给Format结构,例子是传CString到Format结构
             USHORT Format1[40];
             USHORT Format2[]={0,50,'海','康',' ',' ','年','1','1','1','1','\0'};
             CString str="年1111Test";
             int len=strlen(str);
             LPTSTR pTemp=str.GetBuffer(0);
             Format1[0]=Format1[1]=0;              //显示位置坐标0,0
             //copy第一个汉字,高位在前,地位在后
              memcpy((UCHAR *)(Format1+2)+1,&pTemp[0],1);
              memcpy((UCHAR *)(Format1+2),&pTemp[1],1);                                           
             len-=2;                                        //剩余要显示的非汉字字符
             for(int i=3;i<len+4;i++)                   //注意汉字只算一个字符,因此从i=3开始  
             {
                Format1[i]=pTemp[i-1];                //字符串从2开始
             }
             Format1[len+4]='\0';                       //显示字符数 加上表示显示位置的字符数 
             for(i = 0; i < GetTotalDSPs(); i++)
             {
                SetOsdDisplayMode(ChannelHandle[i], 255, TRUE, 1, Format1, Format2);
                SetOsd(ChannelHandle[i], TRUE);
             }
      

  18.   

    USHORT Format2[40] = {24, 50, _OSD_YEAR4, '-',_OSD_MONTH2,'-',_OSD_DAY,'-',  _OSD_HOUR24, ':', _OSD_MINUTE,':', _OSD_SECOND, '\0'};
    你这样子写就会显示实时时间了
      

  19.   

    /////////////////////////////////////////////
      L := 0;
      Format1[0] := 24;
      Format1[1] := 54;
      //if 1=1 then begin
      //str := '第' + '' + inttostr(i + 1) + '' + '路';
      str:=Trim(Memo1.Text);
      {if (RadioGroup2.ItemIndex = 0) then
      begin
      str := trim(edit4.Text);
      end; }
      nLength := Length(str);
      m := 1;
      while m < nLength+1  do begin
        wH := str[m];
        wL := str[m + 1];
        if (ord(wH) > 128) then
        begin
          m := m + 1;
          wFormat := ord(wH) * 16 * 16 + ord(wL);
        end
        else
          wFormat := ord(wH);
        Format1[L + 2] := wFormat;
        L := L + 1;
        m := m + 1;
      end;
      Format1[L + 2] := Ord(#0);
      //end
      //else
      //Format1[2] := Ord(#0);
      SetOsdDisplayMode(i, 255, false, 1, @Format1, @Format2);
      Result := True;
      

  20.   

    procedure TMain_frm.SetOSDFormat(ChannelNum: Integer);
    Var
      L, M, nLength: Integer;
      Format1, Format2: Array[0..40] Of Word;
      wFormat: Word;
      Str: String;
      wH, wL: Char;
    Begin
      L := 0;
      Format1[0] := 8;                      //X坐标
      Format1[1] := 32;                     //Y坐标
      Str := '窗口'+IntToStr(ChannelNum + 1);
      nLength := Length(Str);
      M := 1;
      While M < nLength + 1 Do
      Begin
        wH := Str[M];
        wL := Str[M + 1];
        If (Ord(wH) > 128) Then
        Begin
          M := M + 1;
          wFormat := Ord(wH) * 16 * 16 + Ord(wL);
        End
        Else
          wFormat := Ord(wH);
        Format1[L + 2] := wFormat;
        L := L + 1;
        M := M + 1;
      End;
      Format1[L + 2] := Ord(#0);
      //===============================================
      Format2[0] := 8;                      //X坐标
      Format2[1] := 5;                      //Y坐标
      Format2[2] := _OSD_YEAR4;
      Format2[3] := Ord('-');
      Format2[4] := _OSD_MONTH2;
      Format2[5] := Ord('-');
      Format2[6] := _OSD_DAY;
      Format2[7] := Ord(' ');
      Format2[8] := _OSD_HOUR24;
      Format2[9] := Ord(':');
      Format2[10] := _OSD_MINUTE;
      Format2[11] := Ord(':');
      Format2[12] := _OSD_SECOND;
      Format2[13] := Ord(' ');
      Format2[14] := _OSD_CWEEK1 ;  
      Format2[15] := Ord(#0);
      //===============================================
      SetOsdDisplayMode(ChannelNum, 255, False, 1, @Format1, @Format2);
      {
      当值为1 时,OSD 的亮度根据背景的亮度来调整,但背景较亮时,OSD 亮度自动调低,但背景较暗时,OSD 亮度自动调亮。原来的闪烁功能关闭。 
    当值为 0 时, OSD的亮度不做调整
      }
    end;