I have a program written in C and it's beeing developed under Visual Studio 2012.
My program uses characters not available in Raster fonts, so I changed cmd.exe font to Consolas and my characters (á, é, í, etc.) worked.
But, when I open my program, the console still remains in Raster font. I don't know where I should change to make the Consolas globally accepted.
Thanks in advance.
Here some code I scraped together from several sources.
Allows me to use codepages, avoids unicode.
However, wprintf() etc should work, too.
Only consolas and lucida console work sofar. Includes an attempt to get a similar size.
Checks include the validitycheck of the nFont index.
That may be unneeded, in which case you can leave out the undocumented call to kernel32 routine GetNumberOfConsoleFonts().
Hans says it won't work on XP, docs say minimum _WIN32_WINNT is 0x500 which would include XP. Haven't tried yet.
Jan
static void strcpytoW(WCHAR *dst, const char *src)
{
WCHAR c;
while ((c=*src++)!=0) *dst++=c;
*dst=0;
}
/*************************************/
typedef DWORD (WINAPI *FN_NUMCONSOLEFONT)();
FN_NUMCONSOLEFONT GetNumberOfConsoleFonts;
static bool setfont(const HANDLE h, char *facename, CONSOLE_FONT_INFOEX &in,CONSOLE_FONT_INFOEX &out)
{
in.cbSize=out.cbSize=sizeof(in);
strcpytoW(in.FaceName,facename);
if (!SetCurrentConsoleFontEx(h,FALSE,&in)) return false;
HMODULE hm = ::GetModuleHandleA("KERNEL32.DLL");
if (!hm) return false;
GetNumberOfConsoleFonts = (FN_NUMCONSOLEFONT) GetProcAddress(hm, "GetNumberOfConsoleFonts");
if (!GetNumberOfConsoleFonts) return false;
DWORD numConsoleFonts=GetNumberOfConsoleFonts();
if (!GetCurrentConsoleFontEx(h,FALSE,&out)) return false;
return out.nFont>=0 && out.nFont<numConsoleFonts && _wcsicmp(in.FaceName,out.FaceName)==0;
}
/*************************************/
static char *set_console(char *facename,int page)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_FONT_INFOEX fi={sizeof(fi),-1,{0,0},54,700},newfi;
CONSOLE_FONT_INFO curfi;
if (!GetCurrentConsoleFont(hStdout,FALSE,&curfi)) return NULL;
for (fi.dwFontSize=curfi.dwFontSize;;fi.dwFontSize.Y++)
{
if (!setfont(hStdout,facename,fi,newfi))
{
facename="Lucida Console";
if (!setfont(hStdout,facename,fi,newfi)) return NULL;
}
if (newfi.dwFontSize.X>=curfi.dwFontSize.X) break;
}
if (!SetConsoleOutputCP(page)) return NULL;
return facename;
}
/*************************************/
int main(int argc, char *argv[])
{
char *faceused;
if ((faceused=set_console("Consolas",1252))!=NULL)
printf("Console succesful, using %s\n",faceused);
else puts("Console failed");
puts("\x86 \x87 \xa7 \xa9 \xae \xb1 \xbc");
Press Ctrl-F5 to start executing the program. Before it returns to VS, it says "Press any key...". This gives you the opportunity to click on the window's upper left corner, properties and change the font to raster fonts there, too.
Related
I want to get the full version number for Windows, just like CMD does:
I ended up with this MS doc that says:
To obtain the full version number for the operating system, call the
GetFileVersionInfo function on one of the system DLLs, such as
Kernel32.dll, then call VerQueryValue to obtain the
\StringFileInfo\\ProductVersion subblock of the file version
information.
So I tried to use those functions with this code:
#include <Windows.h>
#include <wchar.h>
#pragma comment(lib, "Mincore.lib")
int wmain(int argc, wchar_t* argv[])
{
// GetFileVersionInfoW
LPCWSTR fileName = L"C:\\Windows\\System32\\kernel32.dll";
DWORD fileInfoSize;
fileInfoSize = GetFileVersionInfoSizeW(fileName, NULL);
if (fileInfoSize == 0)
{
fwprintf(stderr, L"\nError code: %u\n", GetLastError());
return;
}
// GetFileVersionInfoW
VOID* pFileVerInfo = malloc(fileInfoSize);
if (pFileVerInfo == NULL)
{
fwprintf(stderr, L"Failed allocating!\n");
return;
}
if (!GetFileVersionInfoW(fileName, 0, fileInfoSize, pFileVerInfo))
{
fwprintf(stderr, L"Error code: %u\n", GetLastError());
free(pFileVerInfo);
return;
}
// VerQueryValueW
LPCWSTR subBlock = L"\\StringFileInfo\\\\ProductVersion";
VS_FIXEDFILEINFO * pFileInfo;
UINT pLen = 0;
if (!VerQueryValueW(pFileVerInfo, subBlock, (LPVOID*)& pFileInfo, &pLen))
{
fwprintf(stderr, L"Error code: %u\n", GetLastError());
return;
}
return 0;
}
However, the VerQueryValueW function fails with code 1813 and I have no idea why. I also have no idea how I can show the full version after calling the function.
Can you help me?
L"\\StringFileInfo\\\\ProductVersion" is not correct. There must be a Language ID in the middle. On my Windows 10 installation, a working string is: L"\\StringFileInfo\\040904B0\\ProductVersion". But maybe this would differ on other systems.
As suggested by Jonathan Potter in comments, you could find the ID by querying \\VarFileInfo\\Translation.
Simpler options to achieve the goal include:
Query VS_FIXEDFILEINFO instead of StringFileInfo
Read the OS version from the Windows API instead of querying a random DLL.
First of all Sorry for my bad English. I am not native English.
I am going to write a program that list all available logical disk drives. Then ask the user to select a drive. then takes a file extension and searches that file type in given drive (including directories and sub-directories). Program should be able to run on windows xp and onward. It should be single stand alone application. I am not expert in C. I have some hands on C#. i have following questions in this regard.
1. Is there any IDE/Tool in which i can write C# like code that directly compiles to single stand alone application for windows?
2. Can you recommend some libs that i can use state forward for this purpose like using in C#? (I have seen dirent and studying it.)
I coppied some code that i am testing as a startup.
#include <windows.h>
#include <direct.h>
#include <stdio.h>
#include <tchar.h>
#include<conio.h>
#include<dirent.h>
//------------------- Get list of all fixed drives in char array. only drive letter is get. not path.
// add ":\" to build path.
char AllDrives[26];
DWORD GetAllDrives()
{
int AvlDrives=0;
DWORD WorkState=-1;
//TCHAR DrivePath[] = _T("A:\\"); //Orignal Type
//start getting for drive a:\ to onward.
char DrivePath[] = {"A:\\"};
//http://www.tenouk.com/cpluscodesnippet/getdrivetype.html
ULONG uDriveMask = _getdrives();
if (uDriveMask == 0)
{
WorkState=GetLastError();
printf("\r\nFailed to Get drives. Error Details : %lu", WorkState);
return WorkState;
}
else
{
WorkState=0xFF;
printf("The following logical drives are being used:\n");
while (uDriveMask) {
if (uDriveMask & 1)
{
UINT drvType=0;
drvType = GetDriveType(DrivePath);
if(drvType==3)
{
AllDrives[AvlDrives]= DrivePath[0];
AvlDrives++;
printf("\r\n%s",DrivePath);
}
}
++DrivePath[0]; //Scan to all scanable number of drives.
uDriveMask >>= 1;
}
}
return WorkState;
}
int main(int argc, char* argv[]) {
char DrivePath[]={"C:\\"};
char CurrentDrive[]={"C:\\"};
DWORD Drives=-1;
int d=0;
for( d=0; d<26; d++)
AllDrives[d]=' ';
Drives=GetAllDrives();
if(Drives >0)
{
int Length= sizeof(AllDrives);
for(int x=0; x<26; x++)
{
if(AllDrives[x]!=' ')
{
printf("\r\nFixed Drive : %c",AllDrives[x]);
}
}
}
getch();
}
You can use visual studio compiler to compile C and C++ in Windows, and it is available with its own IDE. When you install visual studio, it will install required libraries also to compile the C/C++ program. There are other IDEs and compilers available compatible with Windows like DevC++,CodeBlocks.
I'm getting Spotify's window title for my Now Playing plugin with function:
GetWindowText(spotify_window_handle, title, title_length)
but output contain Replacement character \uFFFD.
Ex. Spotify - Killswitch Engage � One Last Sunset
How to replace � with - in C?
Below full code:
char* spotify_title(int window_handle)
{
int title_length = GetWindowTextLength(window_handle);
if(title_length != 0)
{
char* title;
title = (char*)malloc((++title_length) * sizeof *title );
if(title != NULL)
{
GetWindowText(window_handle, title, title_length);
if(strcmp(title, "Spotify") != 0)
{
return title;
}
else
{
return "Spotify is not playing anything right now. Type !botnext command to restart playback.";
}
}
else
{
printf("PLUGIN: Unable to allocate memory for title\n");
}
free(title);
}
else
{
printf("PLUGIN: Unable to get Spotify window title\n");
}
}
// End of Spotify get title function
The replacement character is used during Unicode->Ansi conversions. Without seeing how title is actually declared (is it using char or wchar_t?), my guess is that you are calling the Ansi version of GetWindowText() (aka GetWindowTextA()) and the window title contains a Unicode character that cannot be represented in your OS's default Ansi locale, so GetWindowTextA() replaces that character when converting the window text to Ansi for output. Keep in mind that Windows is actually a Unicode-based OS, so you should use the Unicode version of GetWindowText() (aka GetWindowTextW()) instead, eg:
WCHAR title[256];
int title_length = 256;
GetWindowTextW(spotify_window_handle, title, title_length);
Or:
int title_length = GetWindowTextLengthW(spotify_window_handle);
LPWSTR title = (LPWSTR) malloc((title_length+1) * sizeof(WCHAR));
GetWindowTextW(spotify_window_handle, title, title_length+1);
...
free(title);
Or at least make sure your project is configured to compile for Unicode so that UNICODE and _UNICODE are defined during compiling. That will make GetWindowText() map to GetWindowTextW() instead of GetWindowTextA(). You will then have to use TCHAR for your title buffer, eg:
TCHAR title[256];
int title_length = 256;
GetWindowText(spotify_window_handle, title, title_length);
Or:
int title_length = GetWindowTextLength(spotify_window_handle);
LPTSTR title = (LPTSTR) malloc((title_length+1) * sizeof(TCHAR));
GetWindowText(spotify_window_handle, title, title_length+1);
...
free(title);
This depends on if you are using Unicode or not. Since you say \uFFFD you are most likely in Unicode so
WCHAR *wp;
while ((wp= wcschr(title, '\uFFFD'))!=NULL) {
*wp= L'-';
}
Assuming the strings are arrays of wchar_t:
wchar_t * p = wcschr(title, `\uFFFD`);
if (p)
*p = `\u002D`;
A while ago I wrote a script in C that used the Windows API functions EnumWindows, SetWindowPos and SetForegroundWindow to automatically arrange windows (by title) in a particular layout that I commonly wanted.
Are there Linux equivalents for these functions? I will be using Kubuntu, so KDE-specific and/or Ubuntu-specific solutions are fine.
The best way to do this is either in the window manager itself (if yours supports extensions) or with the protocols and hints designed to support "pagers" (pager = any non-window-manager process that does window organization or navigation things).
The EWMH spec includes a _NET_MOVERESIZE_WINDOW designed for use by pagers. http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2731465
Raw Xlib or Xcb is pretty rough but there's a library called libwnck specifically designed to do the kind of thing you're talking about. (I wrote the original library long ago but it's been maintained by others forever.) Even if you don't use it, read the code to see how to do stuff. KDE may have an equivalent with KDE-style APIs I'm not sure.
There should be no need to use anything KDE or GNOME or distribution specific since the needed stuff is all spelled out in EWMH. That said, for certain window managers doing this as an extension may be easier than writing a separate app.
Using old school X calls directly can certainly be made to work but there are lots of details to handle there that require significant expertise if you want to iron out all the bugs and corner cases, in my opinion, so using a WM extension API or pager library would be my advice.
#andrewdotn has a fine answer there but you can do this old school as well fairly simply by walking the tree starting at the root window of the display using XQueryTree and fetching the window name with XFetchName then moving it with XMoveWindow. Here is an example that will list all the windows and if any are called 'xeyes' they get moved to the top left. Like most X programs, there is more to it and this should probably be calling XGetWindowProperty to fetch the _NET_WM_NAME extended window manager property but the example works ok as a starter. Compile with gcc -Wall -g -o demo demo.c -lX11
#include <X11/Xlib.h>
#include <stdio.h>
#include <string.h>
static int
EnumWindows(Display *display, Window window, int depth)
{
Window parent, *children;
unsigned int count = 0;
int r = 1, n = 0;
char *name = NULL;
XFetchName(display, window, &name);
for (n = 0; n < depth; ++n) putchar(' ');
printf("%08x %s\n", (int)window, name?name:"(null)");
if (name && strcmp("xeyes", name) == 0) {
XMoveWindow(display, window, 5, 5);
}
if (name) XFree(name);
if (XQueryTree(display, window, &window, &parent, &children, &count) == 0) {
fprintf(stderr, "error: XQueryTree error\n");
return 0;
}
for (n = 0; r && n < count; ++n) {
r = EnumWindows(display, children[n], depth+1);
}
XFree(children);
return r;
}
int
main(int argc, char *const argv[])
{
Display *display = NULL;
if ((display = XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "error: cannot connect to X server\n");
return 1;
}
EnumWindows(display, DefaultRootWindow(display), 0);
XCloseDisplay(display);
return 0;
}
Yes, you can do this using the X Windows protocol. It’s a very low-level protocol so it will take some work. You can use xcb_query_tree to find the window to operate on, and then move it with xcb_configure_window. This page gives some details on how to do it. There’s a basic tutorial on using the library those functions come from, but you’ll probably want to Google for a better one.
It may seem daunting, but it’s not too bad. Here’s a 50-line C program that will move all your xterms 10px to the right:
#include <stdio.h>
#include <string.h>
#include <xcb/xcb.h>
void handle(xcb_connection_t* connection, xcb_window_t window) {
xcb_query_tree_reply_t *tree = xcb_query_tree_reply(connection,
xcb_query_tree(connection, window), NULL);
xcb_window_t *children = xcb_query_tree_children(tree);
for (int i = 0; i < xcb_query_tree_children_length(tree); i++) {
xcb_get_property_reply_t *class_reply = xcb_get_property_reply(
connection,
xcb_get_property(connection, 0, children[i], XCB_ATOM_WM_CLASS,
XCB_ATOM_STRING, 0, 512), NULL);
char* class = (char*)xcb_get_property_value(class_reply);
class[xcb_get_property_value_length(class_reply)] = '\0';
if (!strcmp(class, "xterm")) {
/* Get geometry relative to parent window */
xcb_get_geometry_reply_t* geom = xcb_get_geometry_reply(
connection,
xcb_get_geometry(connection, window),
NULL);
/* Move 10 pixels right */
uint32_t values[] = {geom->x + 10};
xcb_configure_window(connection, children[i],
XCB_CONFIG_WINDOW_X, values);
}
/* Recurse down window tree */
handle(connection, children[i]);
}
}
int main() {
xcb_connection_t *connection;
const xcb_setup_t *setup;
connection = xcb_connect(NULL, NULL);
setup = xcb_get_setup(connection);
xcb_screen_iterator_t screen = xcb_setup_roots_iterator(setup);
handle(connection, screen.data->root);
return 0;
}
There’s no error-checking or memory management, and what it can do is pretty limited. But it should be straightforward to update into a program that does what you want, or to turn it into a general-purpose helper program by adding command-line options to specify which windows to operate on and which operations to perform on them.
As it seems you are not looking specifically for a solution in code, but rather in a desktop environment, you need to take a look at one of the window managers that handle the window placement in such a desktop environment.
KDE's KWin's Window Attributes
Compiz (GNOME) has "Window Rules" and "Place Windows" in the CompizConfig Settings Manager application. See e.g. here
Openbox seems a lot harder to get right, although they link to a GUI tool at the bottom of this page.
The problem with using X directly is that X in itself knows nothing about your desktop environment (panels, shortcuts, etc.) and you'll have to compensate manually.
After googling for this, I'm surprised KDE is the only one that has a simple way to do this.
I really need your help because I'm having many problems integrating one .DLL function into my Console Application.This .DLL consists on getting 2 chars(Char a and Char b)(Input) and adding them to one char.For example:
Char A=H
Char B=I
Output=HI
But here's the problem.When I compile the console application and when I run it,it says that the function hasn't been detected.And here's my question..Why the hell doesn't it find the function even though in the .def file I've listed the LIBRARY and the only exported function?Please help me.
THIS IS THE .DLL SOURCE
#include "stdafx.h"
char concatenazione(char a,char b)
{
return a+b;
}
**THIS IS THE .DEF FILE OF THE .DLL**
LIBRARY Concatenazione
EXPORTS
concatenazione #1
**And this is the dllmain.cpp**
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
**This is the Console Application partial source(For now it just includes the functions import part)**
#include <iostream>
#include <windows.h>
#include <stdio.h>
typedef int (__cdecl *MYPROC)(LPWSTR);
int main( void )
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("C:\\ConcatenazioneDiAyoub.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "concatenazione");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
**The Console Applications runs fine but the output is "Message printed from executable".This means that the function hasn't been detected.**
Ok, I looked at what you have above and wondered where in your code you import the dll. I'm kind of new at this myself, so I found this article on how to do it.
If I understand correctly, in your console application you need to have a line like (assuming the name of your dll is "your.dll":
[DllImport("your.Dll")]
by the way, welcome to Stack Overflow, I noticed it is your first day! CHEERS!