How can I make the command prompt window open in the top left corner? - c++

I'm fairly new (about 10 weeks into an level 1 high school course) and I'm trying to see how I can format the command prompt window. I've learned how to set the size of the window, but not the position. I'm using code::blocks on a windows XP

First, Read This
Then, try these... (in a batch file)
Set mycmdHeight=40
Set mycmdWidth=80
Set mycmdxPos=0
Set mycmdyPos=120
Or, programmatically, look here or here

You can use windows function to move the console windows in your desire location.
First look the function to return the handle of current windows.
HWND WINAPI GetConsoleWindowNT(void)
{
// declare function pointer type
typedef HWND WINAPI (*GetConsoleWindowT)(void);
// declare one such function pointer
GetConsoleWindowT GetConsoleWindow;
// get a handle on kernel32.dll
HMODULE hK32Lib = GetModuleHandle(TEXT("KERNEL32.DLL"));
// assign procedure address to function pointer
GetConsoleWindow = (GetConsoleWindowT)GetProcAddress(hK32Lib,TEXT("GetConsoleWindow"));
// check if the function pointer is valid
// since the function is undocumented
if ( GetConsoleWindow == NULL ) {
return NULL;
}
// call the undocumented function
return GetConsoleWindow();
}
Use above function to get the handle of current window.
HWND hwnd = GetConsoleWindowNT();
Now, you can move your windows at your desire location using MoveWindow function like below:
MoveWindow(hWnd,1230,750,200,100,TRUE);
You can get the complete sample program here.

Related

FindWindowA not finding some windows

I'm new to c++ and FindWindowA is working for some processes and not others, for example:
FindWindowA(NULL, "Discord"); will work
but FindWindowA(NULL, "Fortnite"); won't.
anyone know why?
Thanks.
FindWindow only finds top level windows. If you are searching for an exact match with the title of the window, then you must take into account hidden characters (space, tab, etc.).
Even if you find the window title, it will only work if that window isn't localized—i.e., if the program that creates that window is localized for a different language, then you must also localize your search string.
A more reliable approach is to search for the class name, since this will typically not be localized: FindWindow("myclass", NULL);
Of course this will still fail if there is a hidden top level window that creates a child window containing the window you are looking for. To get that window, you can call EnumWindows to get the handle of each top level window, and for each top level window found, you then call EnumChildWindows.
Fortnite's window has a space or two
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
sd.OutputWindow = FindWindow((L"UnrealWindow"), (L"Fortnite "));
sd.SampleDesc.Count = 1;
sd.Windowed = TRUE;

C++ Winapi - Get Directory (path) identifier

I'm using Winapi's function SHBrowseForFolder and I need to set a default folder for browsing. To achieve that, I need to get the desired default folder's "PIDL". I can get the "PIDL" using this function: SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot); but as you can see, the second parameter is another identifier "nCSIDL" (type int).
How can I get a path's indentifier by path (LPCSTR)?
This is my code:
TCHAR szDir[MAX_PATH];
BROWSEINFO bInfo;
HWND hwnd = ObPanelAPI::GetPanelHandleByName("*Current");
bInfo.hwndOwner = hwnd;
bInfo.pszDisplayName = szDir;
bInfo.lpszTitle = "Seleccionar directorio"; //Dialog title
bInfo.ulFlags = 0 ;
bInfo.lpfn = NULL;
bInfo.lParam = 0;
bInfo.iImage = -1;
//Default folder set
LPITEMIDLIST pidlRoot = NULL;
//*******I NEED TO GET nCSIDL HERE********
SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);
bInfo.pidlRoot = pidlRoot;
LPITEMIDLIST lpItem = SHBrowseForFolder(&bInfo);
I'm using Winapi's function SHBrowseForFolder and I need to set a default folder for browsing. To achieve that, I need to get the desired default folder's "PIDL".
First, you need to differentiate something here. BROWSEINFO has a pidlRoot field, which specifies the top-most folder that the browse dialogs displays. A user cannot select items above that folder. This is NOT the same thing as a "default folder", which is just the folder that is initially selected within the chosen root when the dialog appears.
To set a "default folder", you actually do not need a PIDL, you can use a path string instead (the dialog accepts both). Assign a pointer to the path string to the BROWSEINFO.lParam field and provide a callback function in the BROWSEINFO.lpfn field. Inside the callback, when it receives the BFFM_INITIALIZED notification, it can send the dialog a BFFM_SETSELECTION message, setting the wParam parameter to TRUE and setting the lParam parameter to the path string pointer. This is documented on MSDN:
BFFCALLBACK function pointer
BFFM_SETSELECTION
Specifies the path of a folder to select. The path can be specified as a string or a PIDL.
Now, with that said, the BROWSEINFO.pidlRoot field requires a PIDL, and the BFFM_SETSELECTION message does accept a PIDL as input, so...
I can get the "PIDL" using this function: SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot); but as you can see, the second parameter is another identifier "nCSIDL" (type int).
That function is for retrieving PIDLs for special folders that are pre-defined by Microsoft, like Documents, AppData, User Profiles, etc. These are identified by constant CSIDL values (and KNOWNFOLDERID values on Vista+) which are consistent on every Windows version, though the particular paths may differ from one system to another based on user configuration.
How can I get a path's indentifier by path (LPCSTR)?
There are a few different ways:
IShellFolder::ParseDisplayName(). Call SHGetDesktopFolder() to get the IShellFolder for the Shell namespace root, and then call its ParseDisplayName() to parse the path.
SHParseDisplayName(). Similar to above, but with some additional options available. Do be aware of the following note in the documentation, though:
You should call this function from a background thread. Failure to do so could cause the UI to stop responding.
ILCreateFromPath(). However, it has been observed that ILCreateFromPath() does not always return the same PIDLs that IShellFolder::ParseDisplayName()/SHParseDisplayName() return, that sometimes that difference can cause things like SHBrowseForFolder() to behave incorrectly. I have not personally experienced this, but other people claim they have. You will just have to try it for yourself.

Name of process for active window in Windows 8/10

The following sample has reliably returned the name of the process that is associated with the active window, but does not work with the newer modern/universal apps because it returns the name of a helper process WWAHost.exe on Windows 8 and ApplicationFrameHost.exe on Windows 10 rather than the name of the app.
HWND active_window = GetForegroundWindow();
GetWindowThreadProcessId(active_window, &active_process_id);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, active_process_id);
GetProcessImageFileName(active_process, image_name, 512);
With Windows 10 the ApplicationFrameHost.exe is the process that creates the window handles and is what gets returned by GetWindowThreadProcessId(), is there another Win32 API that can be used to get the active process of universal app that is active?
Also tried using GetApplicationUserModelId() and GetPackageFullName() with no success as they return APPMODEL_ERROR_NO_APPLICATION and APPMODEL_ERROR_NO_PACKAGE respectively because the active_process handle is just the helper process and not the process of the active application.
Any other APIs to use to get the process name of a Modern/Universal application given the hwnd of the window, or otherwise figure out the process name of the universal app is active.
Thanks in advance!
Be sure to use the Spy++ utility when you want to reverse-engineer something like this. Included with Visual Studio, you need the 64-bit version in Common7\Tools\spyxx_amd64.exe. Use Search > Find Window and drag the bullseye to a UWP app, like Weather.
You'll see the window you'll find with GetForegroundWindow(), it has at least 3 child windows:
ApplicationFrameTitleBarWindow
ApplicationFrameInputSinkWindow
Windows.Core.UI.CoreWindow, that's the host window for the UWP app and the one you are interested in. Right-click it and select Properties, Process tab, click the Process ID. That takes you to the real owner process you want to know.
So you just need to make an extra step from the code you already have, you just have to enumerate the child windows and look for one with a different owner process. Some C code, trying to make it as universal as possible without making too many assumptions and not enough error checking:
#include <stdio.h>
#include <Windows.h>
typedef struct {
DWORD ownerpid;
DWORD childpid;
} windowinfo;
BOOL CALLBACK EnumChildWindowsCallback(HWND hWnd, LPARAM lp) {
windowinfo* info = (windowinfo*)lp;
DWORD pid = 0;
GetWindowThreadProcessId(hWnd, &pid);
if (pid != info->ownerpid) info->childpid = pid;
return TRUE;
}
int main()
{
Sleep(2000);
HWND active_window = GetForegroundWindow();
windowinfo info = { 0 };
GetWindowThreadProcessId(active_window, &info.ownerpid);
info.childpid = info.ownerpid;
EnumChildWindows(active_window, EnumChildWindowsCallback, (LPARAM)&info);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.childpid);
WCHAR image_name[MAX_PATH] = { 0 };
DWORD bufsize = MAX_PATH;
QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
wprintf(L"%s\n", image_name);
CloseHandle(active_process);
return 0;
}
Output on the Weather program:
C:\Program Files\WindowsApps\Microsoft.BingWeather_4.5.168.0_x86__8wekyb3d8bbwe\
Microsoft.Msn.Weather.exe
Here is a small console app application that continuously (so you can test it easily selecting different windows on your desktop) display information about the current foreground window process and store process, if any.
Apps can have a window hierarchy that can span multiple processes. What I do here is search the first sub window that has the 'Windows.UI.Core.CoreWindow' class name.
This app uses the UIAutomation API (and also smart pointers, smart BSTRs and smart VARIANTs provided by the #import directive). I suppose you can do the same with standard Windows SDK, but I find the UIAutomation used this way quite elegant.
#include "stdafx.h"
#import "UIAutomationCore.dll"
using namespace UIAutomationClient;
int main()
{
// initialize COM, needed for UIA
CoInitialize(NULL);
// initialize main UIA class
IUIAutomationPtr pUIA(__uuidof(CUIAutomation));
do
{
// get the Automation element for the foreground window
IUIAutomationElementPtr foregroundWindow = pUIA->ElementFromHandle(GetForegroundWindow());
wprintf(L"pid:%i\n", foregroundWindow->CurrentProcessId);
// prepare a [class name = 'Windows.UI.Core.CoreWindow'] condition
_variant_t prop = L"Windows.UI.Core.CoreWindow";
IUIAutomationConditionPtr condition = pUIA->CreatePropertyCondition(UIA_ClassNamePropertyId, prop);
// get the first element (window hopefully) that satisfies this condition
IUIAutomationElementPtr coreWindow = foregroundWindow->FindFirst(TreeScope::TreeScope_Children, condition);
if (coreWindow)
{
// get the process id property for that window
wprintf(L"store pid:%i\n", coreWindow->CurrentProcessId);
}
Sleep(1000);
} while (TRUE);
cleanup:
CoUninitialize();
return 0;
}
Does taking snapshot of running processes and pulling the name out of it by comparing process id not work?
Full reference here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686837(v=vs.85).aspx
But you fix the snapshot with CreateToolhelp32Snapshot().
Or from WTSEnumerateProcesses() and surrounding API?
Pretty sure it worked in Win 8. Is it broken in 10?
Starting from Win10 Anniversary Update ApplicationFrameHost child window return anything but UWP application. It worked only in Tablet mode after relogon.

C++ Windows System Tray wont display message

I have been stuck here for 4 days. I made a function that puts a program in the system tray but the problem here is that it wont show balloon title and message. What Am I doing Wrong? I even made a separate function to determine what windows os we are running on and initialize cbSize based on the Os detected. Any help will be appreciated. Bellow is the function.
EDIT: I am using Windows 7 and the Icon shows up in the system tray but wont show the message or title. I am also doing this Console Application right now as this will be used as a plugin in Unity3D. I want a solution that uses windows api but not windows form as I don't want any new window to open from this.
void createSystemTray()
{
HWND wHandler = GetDesktopWindow();
NOTIFYICONDATA iData;
ZeroMemory(&iData,sizeof(iData));
if(getOsVersion()=="Windows Vista" || getOsVersion()=="Windows 7" || getOsVersion()=="Windows 8" || getOsVersion()=="Windows 8.1")
{
iData.cbSize = sizeof(NOTIFYICONDATA);
}
else if (getOsVersion()=="Windows XP"||getOsVersion()=="Windows XP Professional x64 Edition")
{
iData.cbSize = NOTIFYICONDATA_V3_SIZE;
}
else if (getOsVersion()=="Windows 2000")
{
iData.cbSize = NOTIFYICONDATA_V2_SIZE;
}
else if (getOsVersion()=="UNKNOWN OS")
{
//Assume we have old Windows Os such as Me,95....
iData.cbSize = NOTIFYICONDATA_V1_SIZE;
}
iData.hWnd = wHandler;
iData.uID = 100;
iData.uVersion = NOTIFYICON_VERSION_4;
iData.uCallbackMessage = WM_MESSAGE;
iData.hIcon = LoadIcon(NULL,(LPCTSTR)IDI_WARNING);
lstrcpy(iData.szTip,"My First Tray Icon");
lstrcpy(iData.szInfo,"My App Info");
lstrcpy(iData.szInfoTitle,"My Info Title");
iData.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
Shell_NotifyIcon(NIM_SETVERSION,&iData); //called only when usingNIM_ADD
Shell_NotifyIcon(NIM_ADD,&iData);
}
I added NIF_INFO to the uFlags and the problem is gone. Now it displays everything including text, title and info title.
The code below is what solved it.
iData.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP|NIF_SHOWTIP|NIF_INFO;
Your biggest problem with the code in the question is that you pass the wrong window handle. You have to pass one of your window handles. But instead you pass the window handle of the desktop.
You will need to create a window and use its handle. The window does not need to be visible. I believe that you can use a message only window.
You must also call NIM_SETVERSION after NIM_ADD.
I'm very sceptical of your version switching being based on string equality testing. Your code will break on Windows 9 for instance. Use the version helper functions.
You also perform no error checking. This isn't the easiest function to call but your failure to check for errors makes things even harder than they need to be. Please read the documentation and add error checking code.

Passing parameters to a window call in Windows

I'm new to programming against Windows calls, and I'm trying to figure out a way to pass a parameter to the lpfnWndProc function. I have the following code:
HWND hwnd;
WNDCLASS wc1 = {0};
wc1.lpszClassName = TEXT( "sample" );
wc1.hInstance = 0;
wc1.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc1.lpfnWndProc = DepthWndProc;
Note the line wc1.lpfnWndProc = DepthWndProc; Am I able to pass DepthWndProc a parameter? If so, what does the syntax look like?
Thanks!
You are assigning a function pointer here, not making a call. Thus no passing of arguments.
Having to store extra state with a HWND isn't unusual, a very common requirement for a C++ class wrapper around a window for example. You should keep a map<> to help you retrieve the wrapper object from the window handle value. Using SetWindowLongPtr() with GWLP_USERDATA is possible too but less ideal if you don't control the window creation.
You can call DepthWndProc directly and pass its parameters, but why on earth would you do that? That's not how windows programming works.
You are giving windows a function to call whenever it has a message to send to your window.