改变滚动条位置的问题:SetScrollPos函数

paschen 版主 2015-01-03 04:04:16
一个控制台程序,可以使用SetScrollPos函数吗?

我用这条语句:

BOOL s = SetScrollPos(GetConsoleHwnd(),SB_VERT,20,TRUE);

其中的GetConsoleHwnd()是网上给出的获取控制台程序窗口句柄的函数,如下:


HWND GetConsoleHwnd()
{
#define MY_BUFSIZE 1024 // Buffer size for console window titles.
HWND hwndFound; // This is what is returned to the caller.
char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
// WindowTitle.
char pszOldWindowTitle[MY_BUFSIZE]; // Contains original
// WindowTitle.

// Fetch current window title.

GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);

// Format a "unique" NewWindowTitle.

wsprintf(pszNewWindowTitle,"%d/%d",
GetTickCount(),
GetCurrentProcessId());

// Change current window title.

SetConsoleTitle(pszNewWindowTitle);

// Ensure window title has been updated.

Sleep(40);

// Look for NewWindowTitle.

hwndFound=FindWindow(NULL, pszNewWindowTitle);

// Restore original window title.

SetConsoleTitle(pszOldWindowTitle);

return(hwndFound);
}



运行后,返回值为1,说明设置成功,可是窗口中滚动条位置并没有变化,请问这是为什么?

请牛人指教我要怎么才能实现
...全文
658 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 版主 2015-01-06
  • 打赏
  • 举报
回复
我自己再研究研究,谢谢了
赵4老师 2015-01-05
  • 打赏
  • 举报
回复
或者使用 http://www.autohotkey.com 的.ahk脚本控制终端窗口的滚动条。
赵4老师 2015-01-05
  • 打赏
  • 举报
回复
控制台的功能没必要自己做,通过管道后台操作一个处于另一个桌面下的实际控制台,前台显示完全受你控制的本桌面下的控制台。类似木马技术。 CreateDesktop The CreateDesktop function creates a new desktop on the window station associated with the calling process. It returns a handle that can be used to access the new desktop. The calling process must have an associated window station, either assigned by the system at process creation time or set by SetProcessWindowStation. A desktop is a secure object contained within a window station object. A desktop has a logical display surface and contains windows, menus, and hooks. HDESK CreateDesktop( LPCTSTR lpszDesktop, // name of the new desktop LPCTSTR lpszDevice, // reserved; must be NULL. LPDEVMODE pDevMode, // reserved; must be NULL DWORD dwFlags, // flags to control interaction with other // applications DWORD dwDesiredAccess, // specifies access of returned handle LPSECURITY_ATTRIBUTES lpsa // specifies security attributes of // the desktop ); Parameters lpszDesktop Pointer to a null-terminated string specifying the name of the desktop to be created. Desktop names are case-insensitive and may not contain backslash characters (\). lpszDevice Reserved; must be NULL. The desktop uses the default display driver loaded at boot time. pDevMode Reserved; must be NULL. dwFlags A bit flag parameter that controls how the calling application will cooperate with other applications on the desktop. This parameter can specify zero or the following value: Value Description DF_ALLOWOTHERACCOUNTHOOK Allows processes running in other accounts on the desktop to set hooks in this process. dwDesiredAccess Specifies the access rights the returned handle has to the desktop. This parameter must include the DESKTOP_CREATEWINDOW flag because internally CreateDesktop uses the handle to create a window. In addition, you can specify any of the standard access rights, such as READ_CONTROL or WRITE_DAC, and a combination of the following desktop-specific access rights. Value Description DESKTOP_CREATEMENU Required to create a menu on the desktop. DESKTOP_CREATEWINDOW Required to create a window on the desktop. DESKTOP_ENUMERATE Required for the desktop to be enumerated. DESKTOP_HOOKCONTROL Required to establish any of the window hooks. DESKTOP_JOURNALPLAYBACK Required to perform journal playback on the desktop. DESKTOP_JOURNALRECORD Required to perform journal recording on the desktop. DESKTOP_READOBJECTS Required to read objects on the desktop. DESKTOP_SWITCHDESKTOP Required to activate the desktop using the SwitchDesktop function. DESKTOP_WRITEOBJECTS Required to write objects on the desktop. lpsa Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpsa is NULL, the handle cannot be inherited. The lpSecurityDescriptor member of the structure specifies a security descriptor for the new desktop. If lpsa is NULL, the desktop inherits its security descriptor from the parent window station. Return Values If the function succeeds, the return value is a handle to the newly created desktop. If the specified desktop already exists, the function succeeds and returns a handle to the existing desktop. When you are finished using the handle, call the CloseDesktop function to close it. If the function fails, the return value is NULL. To get extended error information, call GetLastError. Remarks The CreateDesktop function returns a handle that can be used to access the desktop. If the dwDesiredAccess parameter specifies the READ_CONTROL, WRITE_DAC, or WRITE_OWNER standard access rights to access the security descriptor of the desktop object, you must also request the DESKTOP_READOBJECTS and DESKTOP_WRITEOBJECTS access rights. QuickInfo Windows NT: Requires version 3.51 or later. Windows: Unsupported. Windows CE: Unsupported. Header: Declared in winuser.h. Import Library: Use user32.lib. Unicode: Implemented as Unicode and ANSI versions on Windows NT. See Also Window Stations and Desktops Overview, Window Station and Desktop Functions, CloseDesktop, SECURITY_ATTRIBUTES, SetProcessWindowStation, SwitchDesktop console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309
paschen 版主 2015-01-05
  • 打赏
  • 举报
回复
分不够可以再加分,帮我实现了再给100分
paschen 版主 2015-01-05
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
心急吃不了热豆腐。 慢工出细活。 你还可以用普通窗口显示一个看上去象console的窗口,这样一来改变滚动条位置就和其它普通窗口一样了。 填写console窗口的输入和获取console窗口的输出参考下面:
#pragma comment(lib,"user32")
#include <stdio.h>
#include <windows.h>
int main() {
    SECURITY_ATTRIBUTES sa          = {0};
    STARTUPINFO         si          = {0};
    PROCESS_INFORMATION pi          = {0};
    HANDLE              hPipeOutputRead  = NULL;
    HANDLE              hPipeOutputWrite = NULL;
    HANDLE              hPipeInputRead   = NULL;
    HANDLE              hPipeInputWrite  = NULL;
    BOOL                bTest = 0;
    DWORD               dwNumberOfBytesRead = 0;
    DWORD               dwNumberOfBytesWrite = 0;
    CHAR                szMsg[100];
    CHAR                szBuffer[256];

    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    // Create pipe for standard output redirection.
    CreatePipe(&hPipeOutputRead,  // read handle
            &hPipeOutputWrite, // write handle
            &sa,      // security attributes
            0      // number of bytes reserved for pipe - 0 default
            );

    // Create pipe for standard input redirection.
    CreatePipe(&hPipeInputRead,  // read handle
            &hPipeInputWrite, // write handle
            &sa,      // security attributes
            0      // number of bytes reserved for pipe - 0 default
            );

    // Make child process use hPipeOutputWrite as standard out,
    // and make sure it does not show on screen.
    si.cb = sizeof(si);
    si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput   = hPipeInputRead;
    si.hStdOutput  = hPipeOutputWrite;
    si.hStdError   = hPipeOutputWrite;

    CreateProcess (
          NULL, "cmd.exe",
          NULL, NULL,
          TRUE, 0,
          NULL, NULL,
          &si, &pi);

    // Now that handles have been inherited, close it to be safe.
    // You don't want to read or write to them accidentally.
    CloseHandle(hPipeOutputWrite);
    CloseHandle(hPipeInputRead);

    // Now test to capture DOS application output by reading
    // hPipeOutputRead.  Could also write to DOS application
    // standard input by writing to hPipeInputWrite.
    sprintf(szMsg, "dir *.txt /b\nexit\n");
    WriteFile(
          hPipeInputWrite,      // handle of the write end of our pipe
          &szMsg,               // address of buffer that send data
          18,                   // number of bytes to write
          &dwNumberOfBytesWrite,// address of number of bytes read
          NULL                  // non-overlapped.
          );

    while(TRUE)
    {
       bTest=ReadFile(
          hPipeOutputRead,      // handle of the read end of our pipe
          &szBuffer,            // address of buffer that receives data
          256,                  // number of bytes to read
          &dwNumberOfBytesRead, // address of number of bytes read
          NULL                  // non-overlapped.
          );

      if (!bTest){
          sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
          MessageBox(NULL, szMsg, "WinPipe", MB_OK);
          break;
      }

      // do something with data.
      szBuffer[dwNumberOfBytesRead] = 0;  // null terminate
      MessageBox(NULL, szBuffer, "WinPipe", MB_OK);
    }

    // Wait for CONSPAWN to finish.
    WaitForSingleObject (pi.hProcess, INFINITE);

    // Close all remaining handles
    CloseHandle (pi.hProcess);
    CloseHandle (hPipeOutputRead);
    CloseHandle (hPipeInputWrite);

    return 0;
}
感谢,可是这样还是不好用,很多控制台的功能自己做很麻烦 也就是说控制台程序没有一个简单的办法实现对滚动条位置的控制吗?
paschen 版主 2015-01-04
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
控制台的窗口过程不同于普通窗口的窗口过程。 console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309
控制台的窗口过程不同于普通窗口的窗口过程,请问如果要实现要怎么做呢? 帮我简要说一下,不用太复杂的
赵4老师 2015-01-04
  • 打赏
  • 举报
回复
控制台的窗口过程不同于普通窗口的窗口过程。 console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309
TJF331311545 2015-01-04
  • 打赏
  • 举报
回复
用send()发滚动条的消息给控制台窗口?
paschen 版主 2015-01-04
  • 打赏
  • 举报
回复
引用 2 楼 fly_dragon_fly 的回复:
不是有GetConsoleWindow吗
嗯嗯,是的,可以直接使用这个函数,多谢指教 不过这不是重点,关键怎么设置滚动条信息呢,为什么我设置了窗口没有变化
赵4老师 2015-01-04
  • 打赏
  • 举报
回复
心急吃不了热豆腐。 慢工出细活。 你还可以用普通窗口显示一个看上去象console的窗口,这样一来改变滚动条位置就和其它普通窗口一样了。 填写console窗口的输入和获取console窗口的输出参考下面:
#pragma comment(lib,"user32")
#include <stdio.h>
#include <windows.h>
int main() {
    SECURITY_ATTRIBUTES sa          = {0};
    STARTUPINFO         si          = {0};
    PROCESS_INFORMATION pi          = {0};
    HANDLE              hPipeOutputRead  = NULL;
    HANDLE              hPipeOutputWrite = NULL;
    HANDLE              hPipeInputRead   = NULL;
    HANDLE              hPipeInputWrite  = NULL;
    BOOL                bTest = 0;
    DWORD               dwNumberOfBytesRead = 0;
    DWORD               dwNumberOfBytesWrite = 0;
    CHAR                szMsg[100];
    CHAR                szBuffer[256];

    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    // Create pipe for standard output redirection.
    CreatePipe(&hPipeOutputRead,  // read handle
            &hPipeOutputWrite, // write handle
            &sa,      // security attributes
            0      // number of bytes reserved for pipe - 0 default
            );

    // Create pipe for standard input redirection.
    CreatePipe(&hPipeInputRead,  // read handle
            &hPipeInputWrite, // write handle
            &sa,      // security attributes
            0      // number of bytes reserved for pipe - 0 default
            );

    // Make child process use hPipeOutputWrite as standard out,
    // and make sure it does not show on screen.
    si.cb = sizeof(si);
    si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput   = hPipeInputRead;
    si.hStdOutput  = hPipeOutputWrite;
    si.hStdError   = hPipeOutputWrite;

    CreateProcess (
          NULL, "cmd.exe",
          NULL, NULL,
          TRUE, 0,
          NULL, NULL,
          &si, &pi);

    // Now that handles have been inherited, close it to be safe.
    // You don't want to read or write to them accidentally.
    CloseHandle(hPipeOutputWrite);
    CloseHandle(hPipeInputRead);

    // Now test to capture DOS application output by reading
    // hPipeOutputRead.  Could also write to DOS application
    // standard input by writing to hPipeInputWrite.
    sprintf(szMsg, "dir *.txt /b\nexit\n");
    WriteFile(
          hPipeInputWrite,      // handle of the write end of our pipe
          &szMsg,               // address of buffer that send data
          18,                   // number of bytes to write
          &dwNumberOfBytesWrite,// address of number of bytes read
          NULL                  // non-overlapped.
          );

    while(TRUE)
    {
       bTest=ReadFile(
          hPipeOutputRead,      // handle of the read end of our pipe
          &szBuffer,            // address of buffer that receives data
          256,                  // number of bytes to read
          &dwNumberOfBytesRead, // address of number of bytes read
          NULL                  // non-overlapped.
          );

      if (!bTest){
          sprintf(szMsg, "Error #%d reading pipe.",GetLastError());
          MessageBox(NULL, szMsg, "WinPipe", MB_OK);
          break;
      }

      // do something with data.
      szBuffer[dwNumberOfBytesRead] = 0;  // null terminate
      MessageBox(NULL, szBuffer, "WinPipe", MB_OK);
    }

    // Wait for CONSPAWN to finish.
    WaitForSingleObject (pi.hProcess, INFINITE);

    // Close all remaining handles
    CloseHandle (pi.hProcess);
    CloseHandle (hPipeOutputRead);
    CloseHandle (hPipeInputWrite);

    return 0;
}
fly_dragon_fly 2015-01-03
  • 打赏
  • 举报
回复
不是有GetConsoleWindow吗
paschen 版主 2015-01-03
  • 打赏
  • 举报
回复
另外SetScrollInfo函数也试过,同样没成功,请指教

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧