In Windows, Does SetCurrentConsoleFontEx change console's font size? - c++

Other guys recommend the SetCurrentConsoleFontEx function but I don't know how to apply it to my project.
I want to change the font size of only some texts, not all texts.
Does SetCurrentConsoleFontEx() change the console's font size?
Or are there other ways to change it?
If there is, please show me the console function and a simple example.

Here is an example of using SetCurrentConsoleFontEx to change the console's font size. This affects the entire console window -- so like Joachim Pileborg already said, if you want mixed font sizes in a single console window, this won't help you.
#define _WIN32_WINNT 0x500
#include <Windows.h>
// PrintChars sends ASCII characters to console output
// for demonstration purposes.
// depends only on Win32 API
static void PrintChars() {
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD num_written;
static const char* cr_lf = "\r\n";
for(char c=' '; c<'\x7f'; ++c) {
WriteFile(hStdout, &c, 1, &num_written, NULL);
if(c % 16 == 15) WriteFile(hStdout, cr_lf, 2, &num_written, NULL);
}
WriteFile(hStdout, cr_lf, 2, &num_written, NULL);
}
// WaitEnter blocks execution until the user
// presses the enter key.
// depends only on Win32 API
static void WaitEnter() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
char buffer;
DWORD num_read;
do {
num_read = 0;
ReadFile(hStdin, &buffer, 1, &num_read, NULL);
} while(num_read && buffer != '\n');
}
int main() {
// Display some example characters
PrintChars();
// Wait for the user to see how the current font looks
WaitEnter();
// Get a handle to the current console screen buffer
HANDLE hcsb = CreateFileA("CONOUT$", GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
CONSOLE_FONT_INFOEX cfi = {sizeof(cfi)};
// Populate cfi with the screen buffer's current font info
GetCurrentConsoleFontEx(hcsb, FALSE, &cfi);
// Modify the font size in cfi
cfi.dwFontSize.X *= 2;
cfi.dwFontSize.Y *= 2;
// Use cfi to set the screen buffer's new font
SetCurrentConsoleFontEx(hcsb, FALSE, &cfi);
// Wait for the user to see the difference before exiting
WaitEnter();
CloseHandle(hcsb);
}

Related

How does one tell Windows 10 to tile, center, or stretch desktop wallpaper using WIN32 C/C++ API?

Goal: using C++, the Win32 SDK and Visual Studio 2019 to set the desktop wallpaper to be centered or tiled or stretched.
One can use SystemParametersInfo() to change the wallpaper. No problem at all.
Problem is telling the system to tile or center or stretch the wallpaper image.
Reading on the web, whether the wallpaper image is centered, tiled or stretched depends on a pair of registry entries:
HKCU\Control Panel\Desktop\TileWallpaper
HKCU\Control Panel\Desktop\WallpaperStyle
MS' WIN32 docs tell how to change the image but I can't find anything describing how to change the layout.
I have the following code. It is a console app project, the functions ripped out of my larger MFC app, thus the function names. This project's character set is set to Unicode, thus my use of W functions.
It does change the wallpaper image, but the wallpaper is always tiled, regardless of which of the onWallpaper___() functions are called.
Windows seems to completely ignore the registry changes. I have verified that my code does indeed change the registry entries' values.
Question: How does one tell Windows 10 to tile, center, or stretch desktop wallpaper using WIN32 C/C++ API?
Question: Are there different registry entries that should be used?
#include <Windows.h>
#include <iostream>
#include <string>
#include <cassert>
const int CENTERED = 0;
const int TILED = 1;
const int STRETCHED = 2;
void set_wallpaper_registry_keys(int discriminant) {
BOOL rtn;
HKEY hKey;
DWORD TileWallpaper = 0;
DWORD WallpaperStyle = 0;
switch (discriminant) {
case CENTERED: {
TileWallpaper = 0;
WallpaperStyle = 1; // some sources say use 6, makes no difference.
}
break;
case TILED: {
TileWallpaper = 1;
WallpaperStyle = 0;
}
break;
case STRETCHED: {
TileWallpaper = 0;
WallpaperStyle = 2;
}
break;
default: {
assert(false);
}
break;
}
std::wstring key_name(L"Control Panel\\Desktop");
rtn = RegOpenKeyEx(HKEY_CURRENT_USER, key_name.c_str(), 0, KEY_ALL_ACCESS, &hKey);
assert(rtn == ERROR_SUCCESS);
rtn = RegSetValueEx(hKey, L"TileWallpaper", 0, REG_DWORD, (BYTE *)&TileWallpaper, sizeof(DWORD));
assert(rtn == ERROR_SUCCESS);
rtn = RegSetValueEx(hKey, L"WallpaperStyle", 0, REG_DWORD, (BYTE *)&WallpaperStyle, sizeof(DWORD));
assert(rtn == ERROR_SUCCESS);
rtn = RegFlushKey(hKey);
assert(rtn == ERROR_SUCCESS);
rtn = RegCloseKey(hKey);
assert(rtn == ERROR_SUCCESS);
}
void OnWallpaperCentered() {
BOOL rtn;
set_wallpaper_registry_keys(CENTERED);
// set current image as wallpaper: SPI_SETDESKWALLPAPER
std::wstring fn = L"c:\\tmp\\stars.jpg";
rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void *) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
assert(rtn == TRUE);
}
void OnWallpaperTiled() {
// TODO: Add your command handler code here
BOOL rtn;
set_wallpaper_registry_keys(TILED);
std::wstring fn = L"c:\\tmp\\snail.jpg";
rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void *) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
assert(rtn == TRUE);
}
void OnWallpaperStretched() {
// TODO: Add your command handler code here
BOOL rtn;
set_wallpaper_registry_keys(STRETCHED);
std::wstring fn = L"c:\\tmp\\civ4.jpg";
rtn = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (void*) (fn.c_str()), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
assert(rtn == TRUE);
}
int main() {
//OnWallpaperTiled(); // Tiles the wallpaper
OnWallpaperCentered(); // Tiles the wallpaper as well
//OnWallpaperStretched(); // Tiles the wallpaper too
std::cout << "Hello World!\n";
}
Try IDesktopWallpaper interface and IActiveDesktop interfaces.
Create objects for them by creating CLSID_DesktopWallpaper and CLSID_ActiveDesktopobjects.

C++ changing image on user input in WinAPI

I am having issues in getting my .bmp image displayed to change to another one on user input. The image can be successfully printed at the start (title.bmp), but is supposed to change when pressing 1 or 2 followed by enter (to introduction.bmp & start.bmp). I must be missing something!
Where this happens is around the bottom of the code from while (running == 1) { so skip down to there.
I am using loadImage("title.bmp"); to print my images (I change the filename appropriately of course), and cin >> menuSelection; to pause the program and wait until the user presses one or two followed by enter.
I've searched many, many pages on how to print and change images in WinAPI, and this is the closest I can get. If there is any other information I have missed please tell me and I will comment it. Thanks in advance for helping!
//These are the libraries (external files) to include at the start.
#include <cstdio>
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>
using namespace std;
//Defining the [global] variables that will be used throughout the program
int running = 1;
int menuSelection = 0;
int userInput;
int userInputDummy;
int intPointer;
//Starter variables used in creating a window and printing images. These are global.
HDC imageDC; // the DC to hold our image
HBITMAP imageBmp; // the actual bitmap which contains the image (will be put in the DC)
HBITMAP imageBmpOld; // the DC's old bitmap (for cleanup)
const int screenSize_X = 640;
const int screenSize_Y = 480;
//Functions! Sections of code to re-used in the program
// Function to load the image into our DC so we can draw it to the screen
void loadImage(const char* pathname)
{
imageDC = CreateCompatibleDC(NULL); // create an offscreen DC
imageBmp = (HBITMAP)LoadImageA( // load the bitmap from a file
NULL, // not loading from a module, so this is NULL
pathname, // the path we're loading from
IMAGE_BITMAP, // we are loading a bitmap
0, 0, // don't need to specify width/height
LR_DEFAULTSIZE | LR_LOADFROMFILE// use the default bitmap size (whatever the file is), and load it from a file
);
imageBmpOld = (HBITMAP)SelectObject(imageDC, imageBmp); // put the loaded image into our DC
}
// Function to clean up
void cleanUpImage()
{
SelectObject(imageDC, imageBmpOld); // put the old bmp back in our DC
DeleteObject(imageBmp); // delete the bmp we loaded
DeleteDC(imageDC); // delete the DC we created
}
// The function to draw our image to the display (the given DC is the screen DC)
void drawImage(HDC screen)
{
BitBlt(
screen, // tell it we want to draw to the screen
0, 0, // as position 0,0 (upper-left corner)
screenSize_X, // width of the rect to draw
screenSize_Y, // height of the rect
imageDC, // the DC to get the rect from (our image DC)
0, 0, // take it from position 0,0 in the image DC
SRCCOPY // tell it to do a pixel-by-pixel copy
);
}
// A callback to handle Windows messages as they happen
LRESULT CALLBACK wndProc(HWND wnd, UINT msg, WPARAM w, LPARAM l)
{
// what kind of message is this?
switch (msg)
{
// we are interested in WM_PAINT, as that is how we draw
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC screen = BeginPaint(wnd, &ps); // Get the screen DC
drawImage(screen); // draw our image to our screen DC
EndPaint(wnd, &ps); // clean up
}break;
// we are also interested in the WM_DESTROY message, as that lets us know when to close the window
case WM_DESTROY:
PostQuitMessage(0);
break;
}
// for everything else, let the default window message handler do its thing
return DefWindowProc(wnd, msg, w, l);
}
// A function to create the window and get it set up
HWND createWindow(HINSTANCE inst)
{
WNDCLASSEX wc = { 0 }; // create a WNDCLASSEX struct and zero it
wc.cbSize = sizeof(WNDCLASSEX); // tell windows the size of this struct
wc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); // tell it to use the normal arrow cursor for this window
wc.hInstance = inst; // give it our program instance
wc.lpfnWndProc = wndProc; // tell it to use our wndProc function to handle messages
wc.lpszClassName = TEXT("DisplayImage"); // give this window class a name.
RegisterClassEx(&wc); // register our window class with Windows
// the style of the window we want... we want a normal window but do not want it resizable.
int style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; // normal overlapped window with a caption and a system menu (the X to close)
// Figure out how big we need to make the window so that the CLIENT area (the part we will be drawing to) is
// the desired size
RECT rc = { 0,0,screenSize_X,screenSize_Y }; // desired rect
AdjustWindowRect(&rc, style, FALSE); // adjust the rect with the given style, FALSE because there is no menu
return CreateWindow( // create the window
TEXT("DisplayImage"), // the name of the window class to use for this window (the one we just registered)
TEXT("Display an Image"), // the text to appear on the title of the window
style | WS_VISIBLE, // the style of this window (OR it with WS_VISIBLE so it actually becomes visible immediately)
100, 100, // create it at position 100,100
rc.right - rc.left, // width of the window we want
rc.bottom - rc.top, // height of the window
NULL, NULL, // no parent window, no menu
inst, // our program instance
NULL); // no extra parameter
}
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// _________________________________________________________________________________________
// The actual entry point for the program!
// This is Windows' version of the 'main' function:
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show)
{
// load our image
loadImage("title.bmp");
// create our window
HWND wnd = createWindow(inst);
// Do the message pump! keep polling for messages (and respond to them)
// until the user closes the window.
MSG msg;
while (GetMessage(&msg, wnd, 0, 0)) // while we are getting non-WM_QUIT messages...
TranslateMessage(&msg); // translate them
DispatchMessage(&msg); // and dispatch them (our wndProc will process them)
{
while (running == 1) {
//Welcoming the user to the program, and asking them what they want to do (starts functions)
cin >> menuSelection;
//Selecting the introduction option
if (menuSelection == 1) {
loadImage("introduction.bmp");
cin >> userInputDummy;
menuSelection = 0;
}
//Selecting the start option
else if (menuSelection == 2) {
loadImage("start");
cin >> userInputDummy;
menuSelection = 0;
}
//Selecting the exit option
else if (menuSelection == 3) {
menuSelection = 0;
running = 0;
}
}
// once the user quits....
cleanUpImage();
return 0;
return EXIT_SUCCESS;
}
}
you cannot use cin in win32 use an editbox then get the user's input from it as character string then if you want convert it to an integer value otherwise use the API:
GetDlgItemInt(...);
you are also handling only GetMessage in while-loop while you only handle dispatchmessage outside the loop which means you handle it only once, when getmessage fails (the end of program) so the result is a freezing windows as long as there's no one who takes messages from getmessage to the target windo.
the solution: make DispatchMessage inside while loop:
another thing: you pass hwnd to getmessage the result destroying the window won't make the application exit.
take a look at GetMessage() when passing a non-null value:
link text
the correct thing in your case:
while (GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
* don't load image inside loop just load at the time wanted:
make an edit box with style ES_NUMBER and another button names for example change image so when clicked take the content of edit box convert it to integer, check whether it is 1 or 2 then load imaged depending the value.
you may ask "why I can't use iostream input and output streams in win32" because I ask you "where is console windows?" and if it is here what is the role of while-loop (blocking waiting for messages)?

c++ Program to take a screenshot

I am making a program that will click the printscreen key of the keyboard. The code I am using is the following:
INPUT myInput;
myInput.type = INPUT_KEYBOARD;
KEYBDINPUT keyboardInput;
keyboardInput.wScan = 0;
keyboardInput.dwFlags = 0;
keyboardInput.time = 0;
keyboardInput.dwExtraInfo = 0;
keyboardInput.wVk = VK_SNAPSHOT;
myInput.ki = keyboardInput;
SendInput(1, &myInput, sizeof(INPUT));//pressing the printscreen key
keyboardInput.dwFlags = KEYEVENTF_KEYUP;
myInput.ki = keyboardInput;
SendInput(1, &myInput, sizeof(INPUT));//releasing the printscreen key
for some reason the code doesn't work what so ever. If I go to paint and try to paist from clipboard, it will only past whatever printscreen I had done before I had used my program. Also my keyboard doesn't need me to press the "alt" with the print screen in order for it to work..
I had tryed to included the pressing of the Alt key beeeforee the pressing of the printscreen key, as well as the release of the Alt key afffftterr the releasing of the printscreen key, and the difference I got was that when I tried to past it on paint, I paist some kind of a full black screen... This was just a test I did to see if it makes a difference, but my actual keyboard takes screenshots with only the hit of the print screen button.
Any ideas on what I am doing wrong guys?
Edited:
just to let you guys know, the program does in fact compile. I have also added other code that saves the clipboard file to a directory, and I do save a file correctly if I manually hit the print screen button... but if I keep looping this code with the saving to a directory, the same picture of the manually obtained screenshot appears... so that is how I know for sure that there is a problem with the hitting of the printscreen button.
On the windows platform:
You have to follow a certain sequence of simulated key presses.
The code below is a simulates keybd_event() keyboard events and puts the captured screen into the clipboard.
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
keybd_event(VK_MENU, 0, 0, 0); //Alt Press
keybd_event(VK_SNAPSHOT, 0, 0, 0); //PrntScrn Press
keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0); //PrntScrn Release
keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0); //Alt Release
return 0;
}
That is code for taking a screenshot in BMP and to convert it to JPG:
void TakeScreenShot(const std::string& path)
{
//setting to the screen shot
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
//handler of the bitmap that save the screen shot
HBITMAP hBitmap;
//I have to give for it time to make it work
Sleep(100);
//take the screen shot
OpenClipboard(NULL);
//save the screen shot in the bitmap handler
hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
//relese the screen shot
CloseClipboard();
std::vector<BYTE> buf;
IStream *stream = NULL;
HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
CImage image;
ULARGE_INTEGER liSize;
// screenshot to jpg and save to stream
image.Attach(hBitmap);
image.Save(stream, Gdiplus::ImageFormatJPEG);
IStream_Size(stream, &liSize);
DWORD len = liSize.LowPart;
IStream_Reset(stream);
buf.resize(len);
IStream_Read(stream, &buf[0], len);
stream->Release();
// put the imapge in the file
std::fstream fi;
fi.open(path, std::fstream::binary | std::fstream::out);
fi.write(reinterpret_cast<const char*>(&buf[0]), buf.size() * sizeof(BYTE));
fi.close();
}

Crash after SendMessage to TEdit

I'm trying to get data from another program. And... it's giving me an error all the time! Is there something wrong?
HWND hWnd = FindWindow(NULL, L"MyProgram");
if (hWnd)
{
HWND TPageControl = FindWindowEx(hWnd, NULL, L"TPageControl", NULL);
TPageControl = FindWindowEx(hWnd, TPageControl, L"TPageControl", NULL);
HWND TTabSheet = FindWindowEx(TPageControl, NULL, L"TTabSheet", NULL);
HWND TEdit = FindWindowEx(TTabSheet, NULL, L"TEdit", NULL);
int editlength = SendMessage(TEdit, WM_GETTEXTLENGTH, 0, NULL);
TCHAR* Targets = new TCHAR( editlength + 1 );
int count = SendMessage(TEdit, EM_GETLINE, editlength + 1, (LPARAM) Targets);
std::wcout << Targets << "\n";
//delete Targets;
}
but if i'm debugging, it's working.
You are not following the documentation for EM_GETLINE. The first parameter specifies the line index. I'm assuming you are sending this message to a single-line edit control, and it simply gets ignored. The second parameter must hold the length of the buffer:
Before sending the message, set the first word of this buffer to the size, in TCHARs, of the buffer.
The remarks for edit controls are also relevant:
The copied line does not contain a terminating null character.
While parameters for EM_GETLINE get automatically marshaled across process boundaries (like all message parameters for messages in the range 0 to W_USER-1), you might want to consider sending WM_GETTEXT instead, if you are dealing with a single-line edit control:
int editlength = SendMessage(TEdit, WM_GETTEXTLENGTH, 0, NULL);
TCHAR* Targets = new TCHAR[editlength + 1];
int count = SendMessage(TEdit, WM_GETTEXT, editlength + 1, (LPARAM) Targets);
// NUL-terminate buffer in case the text did not fit
Targets[count] = _T('\0');
std::wcout << Targets << "\n";
If you are sending WM_GETTEXT to a hung application your application will hang as well. Call GetWindowText to work around this. The secret life of GetWindowText has additional background information.
If you need to retrieve a specific line from a multi-line edit control the following is more appropriate. In contrast to your code it sends an EM_LINEINDEX and EM_LINELENGTH message to retrieve the appropriate buffer size:
int characterIndex = SendMessage(TEdit, EM_LINEINDEX, lineIndex, 0);
int lineLength = SendMessage(TEdit, EM_LINELENGTH, characterIndex, 0);
TCHAR* pBuffer = new TCHAR[lineLength + 1];
// Set the size of the buffer
*(WORD*)pBuffer = lineLength + 1;
// Retrieve the line
int characterCount = SendMessage(TEdit, EM_GETLINE, lineIndex, (LPARAM)pBuffer);
// NUL-terminate buffer
pBuffer[characterCount] = _T('\0');
A word on why the initial code appears to work when run under a debugger: It's not the debugger, that makes a difference. It's the Debug Build that does. A debug configuration will fill allocated memory with specific byte patterns (0xCD for operator new[]()). The effect of this is that the buffer passed when sending EM_GETLINE is interpreted as having size 0xCDCD (52685 in decimal). In a release configuration on the other hand, the buffer contents are usually 0x00, i.e. the buffer is interpreted as having size 0. This is not to say that the debug build works. It merely masks an error.
I used GetWindowText, works like a sharm I did't want to use fancy calculations. The error really only appears on multiline text, since the buffer size would be calculated correctly.
MS Documentation GetWindowText

Setting the Cursor Position in a Win32 Console Application

How can I set the cursor position in a Win32 Console application? Preferably, I would like to avoid making a handle and using the Windows Console Functions. (I spent all morning running down that dark alley; it creates more problems than it solves.) I seem to recall doing this relatively simply when I was in college using stdio, but I can't find any examples of how to do it now. Any thoughts or suggestions would be greatly appreciated. Thanks.
Additional Details
Here is what I am now trying to do:
COORD pos = {x, y};
HANDLE hConsole_c = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL );
char * str = "Some Text\r\n";
DWDORD len = strlen(str);
SetConsoleCursorPosition(hConsole_c, pos);
WriteConsole(hConsole_c, str, len, &dwBytesWritten, NULL);
CloseHandle(hConsole_c)
The text string str is never sent to the screen. Is there something else that I should be doing? Thanks.
Using the console functions, you'd use SetConsoleCursorPosition. Without them (or at least not using them directly), you could use something like gotoxy in the ncurses library.
Edit: a wrapper for it is pretty trivial:
// Untested, but simple enough it should at least be close to reality...
void gotoxy(int x, int y) {
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
See SetConsoleCursorPosition API
Edit:
Use WriteConsoleOutputCharacter() which takes the handle to your active buffer in console and also lets you set its position.
int x = 5; int y = 6;
COORD pos = {x, y};
HANDLE hConsole_c = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole_c);
char *str = "Some Text\r\n";
DWORD len = strlen(str);
DWORD dwBytesWritten = 0;
WriteConsoleOutputCharacter(hConsole_c, str, len, pos, &dwBytesWritten);
CloseHandle(hConsole_c);
Yeah, you forgot to call SetConsoleActiveScreenBuffer. What exactly was the point of creating your own? Use GetStdHandle(STD_OUTPUT_HANDLE) to get a handle to the existing console.
You were probably using ANSI excape code sequences, which do not work with Windows 32-bit console applications.
#include <windows.h>
#include <iostream.h>
using namespace std;
int main(int argc, char *argv[])
{
int x,y;
cin>>x>>y;
SetCursorPos(x,y); //set your co-ordinate
Sleep(500);
mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0); // moving cursor leftdown
mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0); // moving cursor leftup //for accessing your required co-ordinate
system("pause");
return EXIT_SUCCESS;
}