【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 4286|回复: 0

[DirectX] DirectX全屏模式下中文输入的解决方案

[复制链接]
发表于 2007-3-21 14:15:43 | 显示全部楼层 |阅读模式

      用Asphyre做的画面,设置为全屏后,窗口的VCL控件和输入法窗口都不见了,这是因为D3D的高速刷屏使得以GDI方式绘制的窗口和VCL控件“隐藏”了 , 这样就导致输入法窗口无法显示给用户,打汉字非常的不方便。
      从网上查了查,发现这是个老问题了,解决的方案大致有以下几种:
      1、使用SetDialogBoxMode(true)函数,这个函数的目的就是为了让D3D与GDI的绘制方式兼容,因此要付出相当大的效率作为代价,你会发现D3D的刷新频率降很多,而且火人发现这个方法在有的电脑上无效,相关的代码如下
程序代码:[ 复制代码到剪贴板 ]
    
    Direct3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
          resentParams.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
          @PresentParams, Direct3DDevice);
    Direct3DDevice.SetDialogBoxMode(true);

      2、改变窗口的大小,使这与屏幕分辨率相同,即假全屏方式,同样不如真全屏的绘制快
      3、就是编写D3D自己的输入法窗口,开始以为这个方案太复杂,在网上搜了搜,居然有现存的代码,但一般是C++的,火人尝试翻译成DELPHI,试用效果还可以, 推荐给大家:
先在FormCreate里设Application.OnMessage := WinMessage;
然后在WinMessage函数里捕捉汉字输入法的提示字符串,再显示在屏幕上就行了
程序代码:[ 复制代码到剪贴板 ]
    
  case Msg.message of
    WM_IME_NOTIFY:
      begin
        case Msg.wParam of
          IMN_OPENCANDIDATE, IMN_CHANGECANDIDATE:
            GetCandList(Msg.hwnd);
          IMN_CLOSECANDIDATE:
            begin
              m_strCandList := ''; m_str := '';
            end;
        end;
        caption := m_str + ' ' + m_strCandList;
      end;
  end;

//GetCandList函数  获得候选字列表
function TMainForm.GetCandList(WinHandle: HWND): boolean;
var
  hHimc: HIMC;
  dwSize, i: Integer;
  pcan: CandidateList;
  temp: array of tagCANDIDATELIST;
  buf: array[0..20] of char;
begin
  Result := False;
  if GetKeyboardLayout(0) = 0 then
    Exit;
  hHimc := ImmGetContext(WinHandle); //取得输入上下文
  if hHimc = 0 then
    Exit;

//获取键盘输入字符  
fillchar(buf, 20, 0);
  ImmGetCompositionString(hHimc, GCS_COMPSTR, @buf, 20);
  m_str := buf;

 //获取输入汉字提示字串
  dwSize := ImmGetCandidateList(hHimc, 0, nil, 0);
  if dwSize > 0 then
  begin
    SetLength(temp, dwSize);
    pcan := @temp[0];
    ImmGetCandidateList(hHimc, 0, pcan, dwSize);
    if pcan.dwCount > 0 then
    begin
      i := 1;
      m_strCandList := '';
      while (i < pcan.dwCount - pcan.dwSelection + 1) and (i < pcan.dwPageSize + 1) do
      begin
        m_strCandList := m_strCandList + ' ' + Format('%d.%s', [i, Char(PChar(pcan) +
          pcan.dwOffset[pcan.dwSelection + i])]);
        i := i + 1;
      end;
    end;
  end;
  ImmReleaseContext(WinHandle, hHimc);
  Result := True;
end;


注意:本例程只是为了验证方案3的可行性,因此代码的质量不高,汉字输入还是不很方便。另外好象只支持微软自带的输入法及紫光拼音,不支持智能五笔。而我在玩冒险岛时,全屏模式下可以正常使用智能五笔,不知他们是怎么做到的,望有经验的朋友不吝赐教!


 点击下载此例程

推荐:网友billwillman的改进版(可显示输入法名称及输入预览)

 点击下载此文件
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2024-4-26 10:30

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表