Chinaunix首页 | 论坛 | 博客
  • 博客访问: 198487
  • 博文数量: 264
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 2740
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-03 13:25
文章分类

全部博文(264)

文章存档

2011年(1)

2009年(263)

我的朋友

分类: C/C++

2009-06-04 12:38:38

很多时候,调试GUI程序是很不方便的,通常的做法是使用MessageBox,但是作为一个模态窗口,它经常产生不必要的消息,比如 killfocus, setfocus或者paint,从而影响调试的执行过程。当然,使用vc的调试器也不错,但是这样也很容易造成窗口切换从而产生干扰消息。
9 w5 n3 S# h6 L# M' t) b因此,如果能像在控制台程 序里那样使用cin/cout对象或printf族函数,会使得调试过程方便得多。而通常,windows是不会为GUI程序产生单独的命令行窗口的。所 以我们是看不到使用标准输入输出流输出的东西的。既然系统不提供,那就自己动手“造”出一个来吧!
9 u) m7 N: f, x6 w2 E+ z( N% Y4 |% m( K) ], W' P) Z1 ~: V
下面是一个简单的控制台窗口对象,它可以为你的程序创建一个命令行窗口,并将stdout,stdin和stderr重定向到这个命令行窗口。在程序中建立一个这样的对象之后,就可以直接使用cin/cout/*printf来操纵这个新的命令行窗口了!
3 V4 E. a4 `6 I
: p9 u0 S6 h0 S% r) }- a$ c% B4 N.h文件  P; e+ z! e" O& z, X3 F
#ifndef _CUSTOM_CONSOLE_
, z2 o0 l+ K/ x7 |* o#define _CUSTOM_CONSOLE_. b  J- G) ?, }3 s( g3 C! r
+ b3 t$ U8 ?# C  d! S8 F
#include ! R0 `2 ?2 Y8 ~) |
#include 4 n. I' t/ K6 ~
#include ' E! T, v, z$ x+ i: R. A7 E
#include 2 b2 t$ [. P9 }$ ]% u  r

" G6 ], I  `. A  x; `) r/ [$ qclass Console
2 B4 L7 O/ e5 G{; Y5 Q$ \6 U5 Q  x8 T' j0 F
public:
0 |( T4 p. _! C+ }5 W Console();9 Y' n# I2 V3 {  ~, n- r- g- s
Console(LPCTSTR lpszTitle, SHORT ConsoleHeight = 300, SHORT ConsoleWidth = 80);' {5 v* C5 H% V
~Console();
5 z0 M- B# z3 K4 N, G4 jprivate:0 @7 ^# z. E, h& B/ w) \  t
void Attach(SHORT ConsoleHeight, SHORT ConsoleWidth);
, O$ J7 X  C$ Y" P6 h1 C$ R static BOOL IsExistent;1 }2 b6 K2 \) m9 e! |' k
};8 ^* F* J7 E7 D% N' j5 n& N2 M

! G( [5 p, n% A+ N7 ?#endif" D$ J* W$ ]) X0 H7 L

9 S+ H) [. p1 G6 P.cpp文件
4 _8 l/ u( ?# \$ ~: _( ^5 y: I. U2 [- k- h$ q
#include "***.h"& e( ~- l( {$ Z1 ]- d  m

/ }6 t/ `, M1 Z) w+ s6 ^! K BOOL Console::IsExistent = FALSE;
0 A% g  B% I+ l0 D; X' H% V: d( U Console::Console()% L) U8 \4 \" a% z0 q
{
) Y% e0 f( u) }  if (IsExistent)
. G1 ]( Y9 G7 h0 q8 ^   return;
! s  i! @6 [5 B  AllocConsole();' D" E! P0 m$ b1 ]: f
  Attach(300, 80);: C5 p  J; h" E' S+ N9 h
  IsExistent = TRUE;
' b2 o' P0 D8 l6 D$ S0 T }' c5 ?* {% e% x* Y
Console::Console(LPCTSTR lpszTitle, SHORT ConsoleHeight, SHORT ConsoleWidth); `  U3 W* e+ \2 e# P
{
/ L; P$ ^: a7 R  if (IsExistent)
3 {; z  O  c9 f+ T6 M( j* R   return;
; S8 |! r9 B* @2 o* X0 t  AllocConsole();
- y! H! ^4 [) h' m% J6 \  SetConsoleTitle(lpszTitle);
8 C2 `# W% q( g2 i0 {7 q  Attach(ConsoleHeight, ConsoleWidth);* k3 i1 q, B+ I5 B; b' `
  IsExistent = TRUE;
* \+ h, }+ Z4 @ }7 ?5 m2 G" \& j' @
void Console::Attach(SHORT ConsoleHeight, SHORT ConsoleWidth)! b% M. `' l. l
{
8 G; p8 f& J. e, r  HANDLE  hStd;+ {$ g# k! O# b
  int     fd;; z0 h# I5 n; J. k( A1 q
  FILE    *file;( a+ H8 J. }: U. u) [: E
# t! k$ y2 w# H2 l1 e+ X
// 重定向标准输入流句柄到新的控制台窗口
, b, c  h5 J  b# X& c' ]4 D  hStd = GetStdHandle(STD_INPUT_HANDLE);
/ x  {+ |( }( m3 q4 u: Z' {  fd = _open_osfhandle(reinterpret_cast(hStd), _O_TEXT); // 文本模式1 y- j0 Q# |3 M1 G
  file = _fdopen(fd, "r");
. ?0 I* m7 r) _( l  setvbuf(file, NULL, _IONBF, 0); // 无缓冲& o! T" N9 Z( K% E' z( I1 K, Z- t
  *stdin = *file;& O, {& w; w' Z& @! ^

8 q) ?8 u* i: O' a) |. @3 }// 重定向标准输出流句柄到新的控制台窗口
/ D6 A' e9 U/ g+ M* b! e( B  hStd = GetStdHandle(STD_OUTPUT_HANDLE);% D) K) o% M$ c5 i
  COORD size;
* F( o! e- t. f  size.X = ConsoleWidth;6 L5 |0 d- y3 p) E
  size.Y = ConsoleHeight;
+ G/ g* l7 T( v) a  SetConsoleScreenBufferSize(hStd, size);* z4 L2 t; E5 e, j3 v' q5 V5 l0 i
  fd = _open_osfhandle(reinterpret_cast(hStd), _O_TEXT); //文本模式
! Q. e8 k  I& e6 I! x& D  file = _fdopen(fd, "w");
. Z3 ]( m$ d8 B) }' F& {+ x0 N  setvbuf(file, NULL, _IONBF, 0); // 无缓冲$ s+ _- F7 U( a, D/ N8 Z0 F
  *stdout = *file;
; e$ a6 S* |' t/ n" \
) A6 U" N9 i5 Y/ R" |: q: v// 重定向标准错误流句柄到新的控制台窗口7 d5 P8 {* i( b) o/ O9 I$ i
  hStd = GetStdHandle(STD_ERROR_HANDLE);! u& c* |5 x  ^% M  s* W; Q0 Y0 t6 H
  fd = _open_osfhandle(reinterpret_cast(hStd), _O_TEXT); // 文本模式
' ~% l5 x  Q( q9 D5 i7 O3 O  file = _fdopen(fd, "w");
$ |2 t3 o, W8 b( N  setvbuf(file, NULL, _IONBF, 0); // 无缓冲
- X1 F  y* _+ a8 d, I: |  *stderr = *file;
2 w- g# Y6 `0 [" Z }
5 ^2 u  v; {# a6 n9 P) { Console::~Console()
% K- A4 f9 m0 I. d5 F {; m4 {1 k: b8 p  V* l+ B
  if (IsExistent)
' l, l6 S2 ?" v+ ~' ?  {1 U* U% M2 b7 G; J- Z
   FreeConsole();
) [2 t9 j5 \' y, ~" P   IsExistent = FALSE;
9 Y- U+ r) D6 d$ L; D# X  }
* M3 y4 `% }$ p/ M- p1 Q3 H }
; g" P) G1 h- M) f可以在WinMain里建立这个对象,若在main里建立这个对象,则同样会出现一个新的控制台窗口。
% F9 ?3 z2 ?  J$ I, B#ifdef _DEBUG // 当然,在release版里同样可以使用% y$ Z' }# {9 G) g/ c2 ?: z
Console notused;7 ~% M5 n/ T& _; f% N
#endif
阅读(291) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~