Использование высокоуровневых функций ввода и вывода
В этом документе описаны функции платформы консоли, которые больше не являются частью стратегии развития экосистемы . Мы не рекомендуем использовать это содержимое в новых продуктах, но мы будем продолжать поддерживать существующие использования для неопределенного будущего. Наше предпочтительное современное решение ориентировано на последовательности виртуальных терминалов для обеспечения максимальной совместимости в кроссплатформенных сценариях. Дополнительные сведения об этом решении по проектированию можно найти в классической консоли и в документе виртуального терминала .
В следующем примере используются функции ввода-вывода консоли высокого уровня для операций ввода-вывода консоли. Дополнительные сведения о функциях ввода-вывода консоли высокого уровня см. в разделе «Высокоуровневый ввод-вывод консоли».
В примере предполагается, что режимы ввода-вывода по умолчанию изначально применяются для первых вызовов функций ReadFile и WriteFile. Затем режим ввода изменяется, чтобы включить автономный входной режим и режим ввода эхо для второго вызова ReadFile и WriteFile. Функция SetConsoleTextAttribute используется для задания цветов, в которых будет отображаться последующий текст. Перед выходом программа восстанавливает исходный режим ввода консоли и атрибуты цвета.
Функция примера NewLine используется при отключении режима ввода строки. Он обрабатывает каретки, перемещая позицию курсора в первую ячейку следующей строки. Если курсор уже находится в последней строке буфера экрана консоли, содержимое буфера экрана консоли прокручивается вверх по одной строке.
#include void NewLine(void); void ScrollScreenBuffer(HANDLE, INT); HANDLE hStdout, hStdin; CONSOLE_SCREEN_BUFFER_INFO csbiInfo; int main(void) < LPSTR lpszPrompt1 = "Type a line and press Enter, or q to quit: "; LPSTR lpszPrompt2 = "Type any key, or q to quit: "; CHAR chBuffer[256]; DWORD cRead, cWritten, fdwMode, fdwOldMode; WORD wOldColorAttrs; // Get handles to STDIN and STDOUT. hStdin = GetStdHandle(STD_INPUT_HANDLE); hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE) < MessageBox(NULL, TEXT("GetStdHandle"), TEXT("Console Error"), MB_OK); return 1; >// Save the current text colors. if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) < MessageBox(NULL, TEXT("GetConsoleScreenBufferInfo"), TEXT("Console Error"), MB_OK); return 1; >wOldColorAttrs = csbiInfo.wAttributes; // Set the text attributes to draw red text on black background. if (! SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_INTENSITY)) < MessageBox(NULL, TEXT("SetConsoleTextAttribute"), TEXT("Console Error"), MB_OK); return 1; >// Write to STDOUT and read from STDIN by using the default // modes. Input is echoed automatically, and ReadFile // does not return until a carriage return is typed. // // The default input modes are line, processed, and echo. // The default output modes are processed and wrap at EOL. while (1) < if (! WriteFile( hStdout, // output handle lpszPrompt1, // prompt string lstrlenA(lpszPrompt1), // string length &cWritten, // bytes written NULL) ) // not overlapped < MessageBox(NULL, TEXT("WriteFile"), TEXT("Console Error"), MB_OK); return 1; >if (! ReadFile( hStdin, // input handle chBuffer, // buffer to read into 255, // size of buffer &cRead, // actual bytes read NULL) ) // not overlapped break; if (chBuffer[0] == 'q') break; > // Turn off the line input and echo input modes if (! GetConsoleMode(hStdin, &fdwOldMode)) < MessageBox(NULL, TEXT("GetConsoleMode"), TEXT("Console Error"), MB_OK); return 1; >fdwMode = fdwOldMode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); if (! SetConsoleMode(hStdin, fdwMode)) < MessageBox(NULL, TEXT("SetConsoleMode"), TEXT("Console Error"), MB_OK); return 1; >// ReadFile returns when any input is available. // WriteFile is used to echo input. NewLine(); while (1) < if (! WriteFile( hStdout, // output handle lpszPrompt2, // prompt string lstrlenA(lpszPrompt2), // string length &cWritten, // bytes written NULL) ) // not overlapped < MessageBox(NULL, TEXT("WriteFile"), TEXT("Console Error"), MB_OK); return 1; >if (! ReadFile(hStdin, chBuffer, 1, &cRead, NULL)) break; if (chBuffer[0] == '\r') NewLine(); else if (! WriteFile(hStdout, chBuffer, cRead, &cWritten, NULL)) break; else NewLine(); if (chBuffer[0] == 'q') break; > // Restore the original console mode. SetConsoleMode(hStdin, fdwOldMode); // Restore the original text colors. SetConsoleTextAttribute(hStdout, wOldColorAttrs); return 0; > // The NewLine function handles carriage returns when the processed // input mode is disabled. It gets the current cursor position // and resets it to the first cell of the next row. void NewLine(void) < if (! GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) < MessageBox(NULL, TEXT("GetConsoleScreenBufferInfo"), TEXT("Console Error"), MB_OK); return; >csbiInfo.dwCursorPosition.X = 0; // If it is the last line in the screen buffer, scroll // the buffer up. if ((csbiInfo.dwSize.Y-1) == csbiInfo.dwCursorPosition.Y) < ScrollScreenBuffer(hStdout, 1); >// Otherwise, advance the cursor to the next line. else csbiInfo.dwCursorPosition.Y += 1; if (! SetConsoleCursorPosition(hStdout, csbiInfo.dwCursorPosition)) < MessageBox(NULL, TEXT("SetConsoleCursorPosition"), TEXT("Console Error"), MB_OK); return; >> void ScrollScreenBuffer(HANDLE h, INT x) < SMALL_RECT srctScrollRect, srctClipRect; CHAR_INFO chiFill; COORD coordDest; srctScrollRect.Left = 0; srctScrollRect.Top = 1; srctScrollRect.Right = csbiInfo.dwSize.X - (SHORT)x; srctScrollRect.Bottom = csbiInfo.dwSize.Y - (SHORT)x; // The destination for the scroll rectangle is one row up. coordDest.X = 0; coordDest.Y = 0; // The clipping rectangle is the same as the scrolling rectangle. // The destination row is left unchanged. srctClipRect = srctScrollRect; // Set the fill character and attributes. chiFill.Attributes = FOREGROUND_RED|FOREGROUND_INTENSITY; chiFill.Char.AsciiChar = (char)' '; // Scroll up one line. ScrollConsoleScreenBuffer( h, // screen buffer handle &srctScrollRect, // scrolling rectangle &srctClipRect, // clipping rectangle coordDest, // top left destination cell &chiFill); // fill character and color >
Модуль 1. Ваша первая программа Windows
В этом модуле мы напишем минимальную классическую программу для Windows. Все, что он делает, — это создание и отображение пустого окна. Эта первая программа содержит около 50 строк кода, не считая пустых строк и комментариев. Это будет нашей отправной точкой; позже мы добавим графику, текст, ввод данных пользователем и другие функции.
Если вам нужны дополнительные сведения о создании традиционного классического приложения Windows в Visual Studio, проверка пошаговое руководство. Создание традиционного классического приложения Windows (C++).

Ниже приведен полный код программы:
#ifndef UNICODE #define UNICODE #endif #include LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) < // Register the window class. const wchar_t CLASS_NAME[] = L"Sample Window Class"; WNDCLASS wc = < >; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; RegisterClass(&wc); // Create the window. HWND hwnd = CreateWindowEx( 0, // Optional window styles. CLASS_NAME, // Window class L"Learn to Program Windows", // Window text WS_OVERLAPPEDWINDOW, // Window style // Size and position CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, // Parent window NULL, // Menu hInstance, // Instance handle NULL // Additional application data ); if (hwnd == NULL) < return 0; >ShowWindow(hwnd, nCmdShow); // Run the message loop. MSG msg = < >; while (GetMessage(&msg, NULL, 0, 0) > 0) < TranslateMessage(&msg); DispatchMessage(&msg); >return 0; > LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) < switch (uMsg) < case WM_DESTROY: PostQuitMessage(0); return 0; case WM_PAINT: < PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); // All painting occurs here, between BeginPaint and EndPaint. FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1)); EndPaint(hwnd, &ps); >return 0; > return DefWindowProc(hwnd, uMsg, wParam, lParam); >
Вы можете скачать полный проект Visual Studio из примера Windows Hello World.
Может быть полезно дать краткое описание того, что делает этот код. В последующих разделах код будет подробно рассмотрен.
- wWinMain — это точка входа в программу. При запуске программа регистрирует некоторые сведения о поведении окна приложения. Одним из наиболее важных элементов является адрес функции с именем WindowProc в этом примере. Эта функция определяет поведение окна: его внешний вид, взаимодействие с пользователем и т. д.
- Затем программа создает окно и получает дескриптор, который однозначно идентифицирует окно.
- Если окно создано успешно, программа переходит в цикл while . Программа остается в этом цикле, пока пользователь не закроет окно и не выйдет из приложения.
Обратите внимание, что программа не вызывает функцию явным WindowProc образом, хотя мы и говорили, что именно здесь определена большая часть логики приложения. Windows взаимодействует с программой, передавая ей ряд сообщений. Код внутри цикла while управляет этим процессом. Каждый раз, когда программа вызывает функцию DispatchMessage , она косвенно заставляет Windows вызывать функцию WindowProc один раз для каждого сообщения.
В этом разделе
- Создание окна
- Сообщения окна
- Написание процедуры Window
- Рисование окна
- Закрытие окна
- Управление состоянием приложения
Include windows h что это
Зачем нужен и что делает windows.h ?
В какой-то библиотеке он включается следующим фрагментом:
#ifdef _WIN32
# include
# ifdef small
/* windows.h define small to char */
# undef small
И что за _WIN32, кем и в каком месте он определяется?
Если кто прокомментирует, буду премного благодарен.
Re: Зачем нужен windows.h ?
| От: | Tazman |
| Дата: | 21.07.05 09:44 |
| Оценка: |
Здравствуйте, Chelovek_, Вы писали:
C_> Зачем нужен и что делает windows.h ?
C_> В какой-то библиотеке он включается следующим фрагментом:
Windows.h нужен для того, что бы ты мог использовать в своей программе функционал, предоставляемый операционной системой (Windows 95, 98, NT, 2000, XP).
C_>#ifdef _WIN32
C_># include
C_># ifdef small
C_> /* windows.h define small to char */
C_># undef small
C_> И что за _WIN32, кем и в каком месте он определяется?
C_> Если кто прокомментирует, буду премного благодарен.
А макрос _WIN32 генерируется компилятором, и говорит о том какая версия операционной системы используется.
_WIN16 — 16-ти разрядная
_WIN32 — 32-х разрядная
и вообще макрос _WIN?? говорит о том что используются винды.
Хорошо иметь достойных потомков, но слава принадлежит нашим предкам. (Плутарх)
Re[2]: Зачем нужен windows.h ?
| От: | Chelovek_ |
| Дата: | 21.07.05 10:02 |
| Оценка: |
C_>> Зачем нужен и что делает windows.h ?
C_>> В какой-то библиотеке он включается следующим фрагментом:
T>Windows.h нужен для того, что бы ты мог использовать в своей программе функционал, предоставляемый операционной системой (Windows 95, 98, NT, 2000, XP).
Спасибо. А не могли бы пояснить (пример какой-нибудь), что такое функционал, предоставляемый Windows ?
Например, если программа работет в консольном режиме и занимается вычислениями, она все равно использует какие-то услуги из Windows.h ?
C_>>#ifdef _WIN32
C_>># include
C_>># ifdef small
C_>> /* windows.h define small to char */
C_>># undef small
C_>> И что за _WIN32, кем и в каком месте он определяется?
C_>> Если кто прокомментирует, буду премного благодарен.
T>А макрос _WIN32 генерируется компилятором, и говорит о том какая версия операционной системы используется.
T>_WIN16 — 16-ти разрядная
T>_WIN32 — 32-х разрядная
T>и вообще макрос _WIN?? говорит о том что используются винды.
Еще раз спасибо. А можно сказать компилятору (в настройках каких-нибудь), чтобы он этот макрос не генерировал? (чисто теоретически, на практике понятно, что он много кому может быть нужен).
Re[3]: Зачем нужен windows.h ?
| От: | jazzer | Skype: enerjazzer |
| Дата: | 21.07.05 10:32 | |
| Оценка: |
Здравствуйте, Chelovek_, Вы писали:
C_>>> Зачем нужен и что делает windows.h ?
C_>>> В какой-то библиотеке он включается следующим фрагментом:
T>>Windows.h нужен для того, что бы ты мог использовать в своей программе функционал, предоставляемый операционной системой (Windows 95, 98, NT, 2000, XP).
C_> Спасибо. А не могли бы пояснить (пример какой-нибудь), что такое функционал, предоставляемый Windows ?
C_> Например, если программа работет в консольном режиме и занимается вычислениями, она все равно использует какие-то услуги из Windows.h ?
имеется в виду явное использование. То, что его рантайм использует неявно, тебя не должно волновать.
C_> Еще раз спасибо. А можно сказать компилятору (в настройках каких-нибудь), чтобы он этот макрос не генерировал? (чисто теоретически, на практике понятно, что он много кому может быть нужен).
См. документацию к твоему компилятору.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09
You will always get what you always got If you always do what you always did
Visual C++ подключения библиотеки «windows.h»
Когда в консольных приложения подключаюбиблиотеку «windows.h» и работаю с winapi функциями, то все работает как надо.
То когда тоже самое делаю на Windows Form, например подключаю
#include «windows.h»
.
и вызываю например SendMessage, то выдает много ошибок.
Я в книжке вижел пример, там перед тем как использовать winapi функцию делаю так:
[DllImportAttribute(«user32.dll»)]
static int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
почему не работает обычное подключение библиотеки?
Получается для каждой функции и процедуры надо его определить?
Лучший ответ
Потому что Windows Forms — это .Net, там куча дополнительных приколов и заморочек. Кури мануалы.
Остальные ответы
«почему не работает обычное подключение библиотеки?»
1) Файл Windows.h нужно добавить во внешние зависимости проекта.
Меню Проект — Добавить — Существующий элемент — C:\Program Files\Microsoft SDKs\. версия_винды. \Includes\Windows.h
2) #include нужно добавить в stdafx.h
3) Туда же — #pragma comment(lib, «user32.lib») — для вызова функций из user32.dll
По поводу первого пункта, есть сомнения, что проект будет компилироваться на виндах других версий, ведь той папки там может не оказаться.
Лучше этот файл — а также включенные в него WinUser, WinGdi и т.д. — распространять вместе с исходником и подключать соответственно.
«почему не работает обычное подключение библиотеки?»
Windows.h — не библиотека, а заголовочный файл.
В нём библиотека user32.dll тоже подключена похожим образом, можете сами посмотреть.