冒险解谜游戏中文网 ChinaAVG

标题: 【图像识别汉化研究】directdraw主表面显示文字疑难 [打印本页]

作者: shane007    时间: 2009-5-30 09:51
标题: 【图像识别汉化研究】directdraw主表面显示文字疑难
下面这对对话在研究使用directdraw的游戏汉化时可能能用上。
, E; s! ~% }1 y7 E# c. _+ A$ D. J! P5 L9 |2 i  V8 u
原文# g* I0 w- t" S) E
http://www.qqgb.com/Program/VC/VCJQ/Program_177879.html   
$ u+ U4 ?- v3 T# d; I8 _/ w5 V6 X+ \1 p9 p. M
directdraw主表面显示文字问题 前提:已经Hook了ddraw.dll的几个关键API(包括接口的虚函数表),成功获取到了主表面。 2 d  R$ M' v4 ?) w6 I5 E/ a- r
问题:向主表面的HDC TextOut后,文字是显示出来了,但都保持在屏幕的最顶层,其它窗口经过时也会显示文字。 . w& n! h/ P" A/ C  u
为什么没有附在原窗口(用来显示主表面的)中呢? 第1个回答
5 ?# K4 }! l1 `# k; ]3 D7 L居然还有这种事?HDC是ddraw窗口的DC吗?一个DC绘制的图形不是分离的对象,不可能被拆成两部分显示。后台表面也要同时hook绘制。 . l6 Z  C6 x4 `8 K
--------------------------------------------------------------------------------: u% o: U  h7 |
第2个回答$ p$ E" ~: O, N8 w' T/ F
HDC 是主表面实例指针-> GetDC()的,不是窗口的HDC。后台表面GetDC()失败,应该不是真正的后台,它不是用Flip进行显示的,而是主表面用Blt绘制另外一个非主表面。 - j( U7 f+ K, z: b/ H8 {! D
--------------------------------------------------------------------------------
% t! ~' l% i1 K7 n; `9 u第3个回答
# p# ~0 R5 S. G7 t" V( O7 t5 q窗口界面的DDraw程序肯定不可能使用Flip了。
: D& M1 w9 `8 r7 R! l主表面上绘制东西出界是常有的事情,首先要设置Clipper,而且在绘制的时候还要自己获取窗口坐标进行坐标变换,这样才能保证绘制在窗口上。
+ j$ q6 o5 L+ P9 u: l! ~--------------------------------------------------------------------------------
5 `+ s' P. U1 _# b: L0 R2 O3 B第4个回答' A4 `; Q% S' l9 v! J, k! r
我是想在第3方的视频播放器中显示文字,已经Hook了DDraw.dll,得到了主表面实例指针lpddsPrimary,此时主表面已经设置过了Clipper,
: f  a1 A9 A8 S. |, j/ d! Q我只是lpddsPrimary-> GetDC(),然后Textout,出现显示的文字和画面分离的情况,文字显示的位置正确,但保持在屏幕的最上端,当有其它窗口 4 N, v  G# K: y7 @: A
经过时也会显示文字。难道HDC也要设置Clipper,不会吧,真不知道怎么解决?!
% @: e2 \7 W. x+ L+ i另外是不是可以附加个覆盖页面(overlay),用来显示文字;但覆盖页面GetDC会失败,不能Textout,怎样才能在覆盖页面上显示文字?! 9 X5 J+ L) m9 P% I$ k1 _( V
--------------------------------------------------------------------------------! U- ^  I* @3 h2 o
第5个回答
7 O* N& ^8 Q0 G我也做过这事,,我的方法是注入一个dll,枚举它当前程序里所有的surface,然后分别往枚举出来的surface上textout,看哪个能用,效果最好
. O# q" {! Q6 K6 G  n; N  I  W( T, H. @: ^
C/C++ code  N2 B5 }# _$ s( ^8 d8 \. b
--------------------------------------------------------------------------------
4 o* f9 C3 R7 c/ ~% y' FLPDIRECTDRAWSURFACE7 lpDDSPrimary;//主surface
& N! V8 o/ B6 Y  ~/ t9 ~' m& |* QLPDIRECTDRAWSURFACE7  lpDDS[4];//用来保存枚举出的surface
& }2 J( {) W% `DWORD lpDDAddr = 0x00160e50;//lpDD的地址,通过调试很容易得到
5 [' U0 f8 h$ B+ b+ _LPDIRECTDRAW7 lpDD;
- o( H* c9 m" Y% A! r$ Z) u" lDDSURFACEDESC2 ddsd;- K0 x- U! H  b+ K

& m  V2 h, D! G$ Hint si=0;//surface计数
& c5 h& v# X" X" m: ?  q: q! {DDSCAPS2 ddscaps ;, w. ^+ V, h; t9 M' A* K& U5 o
HRESULT WINAPI _surfaceEnumCallback_GetPrimary( LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID /*lpContext*/ ) {
6 q; s0 K* S* p7 w% b    lpDDS[si] = lpDDSurface;
' a5 X4 W) j. B  W( s    si++;
# @: R  p7 J( A) i5 o1 n. n    wsprintf(buff2, "surface:%8x, width=%d, height=%d, buffCount:%d\n",
& e5 x0 |) Q! c1 v  l. I( `        lpDDSurface, lpDDSurfaceDesc->dwWidth,( j$ k/ q6 [2 [- C" m8 S1 D
        lpDDSurfaceDesc->dwHeight,lpDDSurfaceDesc->dwBackBufferCount);
1 G+ t) D# Y  F    mout(buff2);, `* H: l* y6 ]3 H
    if( lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE ) { //Primary5 J, R) x8 w, B; o0 v
        lpDDSPrimary = lpDDSurface;
3 W2 P9 u( k( ^1 q: Q, Z* j8 ]        wsprintf(buff2, "primary surface: %8x\n", lpDDSurface);
/ y* m2 w+ Q/ v6 R        mout(buff2);
2 e' q& Y( y8 N/ W( J% u    //    lpDDSurface->GetSurfaceDesc(&ddsd);  E+ D; Z" g2 J( x: O
    //  return DDENUMRET_CANCEL;# r2 o- Y- B- e. x7 S! t9 t* P9 E
    }
* u+ Y' D, e6 s& q* c! w: B+ U3 |% y    //lpDDSurface->Release();
: r4 y" c$ }" v# V7 h9 Z7 f8 N2 V    return DDENUMRET_OK;
' \2 S2 R- @5 u2 d+ \+ R9 @) M}
. [2 r/ L" b+ q9 c: m% K9 y//以上是回调函数,下面是枚举8 g0 L" `* [; o7 o6 ~0 [0 |
// Get lpDD
: \) [) s; E# }$ ^- EDWORD addr=0x00385b2c;
1 q* ~& w: \; x/ {( o: `6 rVirtualProtect( ( void * ) addr, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect );
' W1 q* f- o/ D* b1 tlpDDAddr=  *((DWORD*)addr);
4 M, I& T" t' t) _lpDD = (struct IDirectDraw7 *)lpDDAddr;
* N  g: N& X  m' V
, g$ b& ]/ j' Y* Q6 F: i! y// Enum Surface
* S  H' Q& E! U3 \: N1 x3 Amout("now start to enum:\n");' G- ]$ M. I5 D$ g
lpDD->EnumSurfaces( DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, NULL, NULL, _surfaceEnumCallback_GetPrimary );; C7 t' B$ n! t' u6 G$ M
for(int i=0;i<4;i++){* H4 e( e% C8 t+ v6 N
    wsprintf(buff2, "found surface[%d]: %8x\n", i, lpDDS);( I5 u6 M, n* |0 J, Q) i
    mout(buff2);1 I( I& ^! v0 p  U% [2 z, E
}
, o  }4 Z( @) Q2 T5 f4 [2 K0 [5 E- v1 {8 O

8 o" I' g4 c4 i; _2 d/ e--------------------------------------------------------------------------------
# r# k0 z; p- a) P" i( v第6个回答
: q4 J2 u; V0 G  t7 @3 b帮顶 $ a9 W& }6 }  W
--------------------------------------------------------------------------------
- x+ K% l  g8 F  T8 B. W7 q2 M! Y第7个回答
' t6 n+ Z2 o6 J  p在它的backBuffer绘制试试。 . }' ?& Y8 g! ~8 u; j( Q
--------------------------------------------------------------------------------
$ C; [' n; P4 w3 a; t: q* P第8个回答
. h# f* d' S+ n( U" a- D5 ]/ xbackBuffer 无法GetDC(),就无法TextOut & n* p% E0 ~) h2 ?* J# t+ ~) Z
--------------------------------------------------------------------------------
; \  P: u- X( D6 n第9个回答
  }: R1 n1 L9 v7 X" s7 {+ \backBuffer怎么会无法GetDC呢?那那个程序本身是怎么往上绘东西的啊。你看看是不是其它地方错了。
* G% Z" l& M/ K# m& f) h7 U- y--------------------------------------------------------------------------------7 Y# P1 v4 \  T' w
第10个回答
3 R9 @, T' e- S6 ~不会有错,那个程序是解码MP4视频流数据后,用ddraw加以显示,程序本身用不到GetDC,我用是为了显示文字。 5 l9 n7 z  d: H! g. f$ g  G  t  f
--------------------------------------------------------------------------------" F+ \; |; \# @8 \5 G
第11个回答! ~. d7 U  Z; s$ T7 G- B
那程序要往上面绘东西,Blt总得支持吧? 1 f" K+ t8 }, {
你自己建一个Surface,GetDC后TextOut你的文字,然后Blt到那个BackBuffer上去。
  ]% ~6 f8 n1 [# \/ j3 B  F* K* R--------------------------------------------------------------------------------




欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://chinaavg.com/) Powered by Discuz! X3.2