首页
社区
课程
招聘
WINDOWS控制台程序怎样接收WINDOWS消息?
发表于: 2006-2-18 22:55 14541

WINDOWS控制台程序怎样接收WINDOWS消息?

2006-2-18 22:55
14541

是不是
main(){
        while (GetMessage(&msg, NULL, 0, 0))
        {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }

}

在哪里去处理消息了?


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
2
控制台程序和一般的窗口程序区别不大, 系统会自动给它 分配一个控制台窗口而不会给窗口程序分配, 消息循环没有什么不同, 不过控制台程序一般不需要消息循环的
2006-2-19 14:10
0
雪    币: 214
活跃值: (70)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
在窗口里处理,像是这样
        switch (message)
        {

        case        WM_CREATE:
                        OnInitDialog(hwnd);
                        return 0;
        case        WM_PAINT:
                                hdc = BeginPaint(hwnd, &ps) ;
                                GetClientRect (hwnd, &rc) ;
                                hBrush = CreateSolidBrush (fFlipFlop ? RGB(225,225,225) : RGB(0,0,255)) ;
                                FillRect (hdc, &rc, hBrush) ;
                                EndPaint (hwnd, &ps) ;
                                DeleteObject (hBrush) ;
                        return 0;
        case        WM_DESTROY:
                        return 0;
        case        WM_CLOSE:
                        PostQuitMessage (0) ;
                        return 0;
        case        WM_QUIT:
                        return 0;
2006-2-20 18:11
0
雪    币: 202
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
有一个控制台的程序,只要按了ctrl+C后程序可以自动退出
里面好像有这样的消息处理方法,代码一下子找不到了

还想请教一下,如果想在console模式下得到鼠标的位置,改怎么做,谢谢
2006-2-21 13:16
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
对于如何处理ctrl + C消息, 可以用这个函数:
invoke SetConsoleCtrlHandler, ADDR Handler, TRUE
其中Handler是这样一个函数:
Handler PROC _ControlType
;代码略
Handler ENDP

至于得到鼠标(还是光标?)位置, 直接用GetCursorPos函数就可以了
要得到光标位置可以用GetConsoleCursorInfo函数
2006-2-21 23:01
0
雪    币: 234
活跃值: (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
最初由 thebutterfly 发布
控制台程序和一般的窗口程序区别不大, 系统会自动给它 分配一个控制台窗口而不会给窗口程序分配, 消息循环没有什么不同, 不过控制台程序一般不需要消息循环的


问题是在哪里接收消息了?
必须创建一个(隐藏)窗口去接收消息吗?
2006-2-21 23:40
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
7
请注意, 控制台程序和窗口程序唯一的不同就是启动的时候系统会自动给它分配一个控制台窗口, 一个正常的窗口程序完全可以按照控制台程序的方式链接, 这样生成的程序可以照常运行, 照常显示窗口, 只是多了一个没有任何内容的控制台窗口
普通的控制台程序是不需要接收消息的, 特殊情况如处理ctrl+break(C)时系统有专用的函数, 我在5楼的帖子中已经说了

楼主为什么要在控制台程序中处理消息呢?
2006-2-22 18:58
0
雪    币: 161
活跃值: (231)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
2006-2-23 10:32
0
雪    币: 234
活跃值: (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
最初由 thebutterfly 发布
请注意, 控制台程序和窗口程序唯一的不同就是启动的时候系统会自动给它分配一个控制台窗口, 一个正常的窗口程序完全可以按照控制台程序的方式链接, 这样生成的程序可以照常运行, 照常显示窗口, 只是多了一个没有任何内容的控制台窗口
普通的控制台程序是不需要接收消息的, 特殊情况如处理ctrl+break(C)时系统有专用的函数, 我在5楼的帖子中已经说了

楼主为什么要在控制台程序中处理消息呢?


我的程序是这样的(后台执行的,FreeConsole):

main(){
  FreeConsole();
  while(1){
   do_sth();
   Sleep(1000);

  }
}
系统关机或者注销时,我想做一些操作,如保存状态数据等。但现在就是检测不到关机的信号。SetConsoleCtrlHandler的办法好像行不通。
是不是只能创建一个隐藏窗口来检测系统关机或者注销信号?
2006-2-26 21:01
0
雪    币: 214
活跃值: (70)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
给个源码你参考,或者对你有帮助

//====================================================
// Description: A sample to show how to filter cmd.exe
//====================================================
#define WIN32_LEAN_AND_MEAN
#define WINVER 0x0500

//#include <stdio.h>
#include <windows.h>

#define BUFF_SIZE 16384 //16K

HANDLE g_hCmdStdinRead;
HANDLE g_hCmdStdinWrite;
HANDLE g_hCmdStdinWriteDup;
HANDLE g_hChildStdoutRead;
HANDLE g_hChildStdoutWrite;
HANDLE g_hChildStdoutReadDup;
HANDLE g_hInputHandle;
HANDLE g_hBackupStdin;
HANDLE g_hBackupStdout;

//#pragma comment(linker,"/merge:.rdata=.data")
//#pragma comment(linker,"/merge:.text=.data")

//----------------------------------------------------------------------------
void ErrorExit (LPTSTR lpszMessage)
{
//fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}

//----------------------------------------------------------------------------
                BOOL CheckCmd(char* pBuffer)
                {
                if(strcmp(pBuffer, "exit\r\n") == 0)
                {  
                        ExitProcess(0);   
                }
                return TRUE;
                }

//----------------------------------------------------------------------------
int EnterInfoCMD(void)
{
DWORD dwReadCnt;
DWORD dwWriteCnt;
CHAR cBuffer[BUFF_SIZE];
int  nCmdLen;

memset(cBuffer, 0, BUFF_SIZE);
if (! WriteFile(g_hCmdStdinWriteDup, cBuffer, strlen(cBuffer), &dwWriteCnt, NULL)) return -1;
Sleep(300);

if( !ReadFile( g_hChildStdoutReadDup, cBuffer, BUFF_SIZE, &dwReadCnt, NULL) || dwReadCnt == 0) return -1;
if (! WriteFile(g_hBackupStdout, cBuffer, dwReadCnt, &dwWriteCnt, NULL))  return -1;

// Read from a file and write its contents to a pipe.
        for (;;)
        {
                        memset(cBuffer, 0, BUFF_SIZE);
                        if (! ReadFile(g_hInputHandle, cBuffer, BUFF_SIZE, &dwReadCnt, NULL) ||
                        dwReadCnt == 0)
                        break;
                        // Add check-method here
                        CheckCmd(cBuffer);
                        nCmdLen = strlen(cBuffer);
                        if (! WriteFile(g_hCmdStdinWriteDup, cBuffer, dwReadCnt, &dwWriteCnt, NULL)) break;

                        BOOL bStripCmd = TRUE;
                        for(;;)
                        {
                                Sleep(300);
                                memset(cBuffer, 0, BUFF_SIZE);
                                if( !ReadFile( g_hChildStdoutReadDup, cBuffer, BUFF_SIZE, &dwReadCnt, NULL) || dwReadCnt == 0) break;

                                if(bStripCmd)
                                {
                                        if (! WriteFile(g_hBackupStdout, cBuffer + nCmdLen, dwReadCnt - nCmdLen, &dwWriteCnt, NULL))
                                        break;
                                }
                                else
                                {
                                        if (! WriteFile(g_hBackupStdout, cBuffer, dwReadCnt, &dwWriteCnt, NULL))
                                        break;
                                }
                                bStripCmd = FALSE;
                                if(cBuffer[dwReadCnt - 1] == '>') break;     
                        }
        }

// Close the pipe handle so the child process stops reading.
if (! CloseHandle(g_hCmdStdinWriteDup))  ErrorExit("Close pipe failed\n");
return 0;
}

//----------------------------------------------------------------------------
BOOL CreateCMDProcess()
{  
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
BOOL bRtn = FALSE;
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);

// Create the child process.
TCHAR tcsExename[MAX_PATH];
TCHAR tcsParam[MAX_PATH * 2];
TCHAR tcsCmd[MAX_PATH];
if( 0 == GetModuleFileName(NULL, tcsExename, MAX_PATH)
  ||  0 == GetEnvironmentVariable("COMSPEC", tcsCmd, MAX_PATH))
  return FALSE;

// get short filename for command shell program
if( 0 == GetShortPathName(tcsExename, tcsExename, MAX_PATH))
  return FALSE;

bRtn = CreateProcess(NULL,
  tcsCmd,       // command line
  NULL,          // process security attributes
  NULL,          // primary thread security attributes
  TRUE,          // handles are inherited
  0,             // creation flags
  NULL,          // use parent's environment
  NULL,          // use parent's current directory
  &siStartInfo,  // STARTUPINFO pointer
  &piProcInfo);  // receives PROCESS_INFORMATION

if (bRtn == 0)
{
  ErrorExit("CreateProcess failed\n");
  return FALSE;
}
else
{
  CloseHandle(piProcInfo.hProcess);
  CloseHandle(piProcInfo.hThread);
  return bRtn;
}
}

//----------------------------------------------------------------------------
DWORD CmdMain()
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;

// The steps for redirecting child process's STDOUT:
//     1. Save current STDOUT, to be restored later.
//     2. Create anonymous pipe to be STDOUT for child process.
//     3. Set STDOUT of the parent process to be write handle to
//        the pipe, so it is inherited by the child process.
//     4. Create a noninheritable duplicate of the read handle and
//        close the inheritable read handle.

// Save the handle to the current STDOUT.
g_hBackupStdout = GetStdHandle(STD_OUTPUT_HANDLE);   // 得到本进程的当前标准输出
// Create a pipe for the child process's STDOUT.
if (! CreatePipe(&g_hChildStdoutRead,                        //指向读句柄的指针
                                  &g_hChildStdoutWrite,                        // 指向写句柄的指针
                                  &saAttr,                                                // 指向安全属性的指针
                                  0)                                                        // 管道大小
                                  ) ErrorExit("Stdout pipe creation failed\n");

// Set a write handle to the pipe to be STDOUT.
// 设置标准输出到匿名管道
if (! SetStdHandle(STD_OUTPUT_HANDLE, g_hChildStdoutWrite)) ErrorExit("Redirecting STDOUT failed");

// Create noninheritable read handle and close the inheritable read
// handle.

fSuccess = DuplicateHandle(GetCurrentProcess(), g_hChildStdoutRead,
                        GetCurrentProcess(), &g_hChildStdoutReadDup , 0,
                        FALSE,
                        DUPLICATE_SAME_ACCESS);
if( !fSuccess ) ErrorExit("DuplicateHandle failed");

CloseHandle(g_hChildStdoutRead);

// The steps for redirecting child process's STDIN:
//     1.  Save current STDIN, to be restored later.
//     2.  Create anonymous pipe to be STDIN for child process.
//     3.  Set STDIN of the parent to be the read handle to the
//         pipe, so it is inherited by the child process.
//     4.  Create a noninheritable duplicate of the write handle,
//         and close the inheritable write handle.

// Save the handle to the current STDIN.
g_hBackupStdin = GetStdHandle(STD_INPUT_HANDLE);

// Create a pipe for the child process's STDIN.
if (! CreatePipe(&g_hCmdStdinRead, &g_hCmdStdinWrite, &saAttr, 0))
        ErrorExit("Stdin pipe creation failed\n");

// Set a read handle to the pipe to be STDIN.
if (! SetStdHandle(STD_INPUT_HANDLE, g_hCmdStdinRead))
        ErrorExit("Redirecting Stdin failed");

// Duplicate the write handle to the pipe so it is not inherited.
fSuccess = DuplicateHandle(GetCurrentProcess(), g_hCmdStdinWrite,
                        GetCurrentProcess(), &g_hCmdStdinWriteDup, 0,
                         FALSE,                  // not inherited
                         DUPLICATE_SAME_ACCESS);
if (! fSuccess)
        ErrorExit("DuplicateHandle failed");

CloseHandle(g_hCmdStdinWrite);

// Now create the child process.
fSuccess = CreateCMDProcess();
if (! fSuccess)
        ErrorExit("Create process failed");

// After process creation, restore the saved STDIN and STDOUT.
if (! SetStdHandle(STD_INPUT_HANDLE, g_hBackupStdin))
        ErrorExit("Re-redirecting Stdin failed\n");

if (! SetStdHandle(STD_OUTPUT_HANDLE, g_hBackupStdout))
        ErrorExit("Re-redirecting Stdout failed\n");

// Get a handle to the parent's input file.
g_hInputHandle = g_hBackupStdin;

if (g_hInputHandle == INVALID_HANDLE_VALUE)
        ErrorExit("no input file\n");

EnterInfoCMD();
return 0;
}
2006-2-26 22:17
0
雪    币: 216
活跃值: (131)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
如果想让console程序在后台运行,或者让其也在系统托盘留一个图标应怎样做,谢谢
2006-2-28 09:44
0
雪    币: 202
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
大致函数讲一些什么内容和相互之间的关系
2006-2-28 19:53
0
雪    币: 234
活跃值: (104)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
最初由 smarter 发布
如果想让console程序在后台运行,或者让其也在系统托盘留一个图标应怎样做,谢谢


后台执行,调用freeconsole就行了。在explorer中直接双击执行就到后台上去了。
留系统托盘图标和gui程序没有什么不同。
2006-3-1 09:20
0
游客
登录 | 注册 方可回帖
返回
//