Open TDecoratedMDIFrame Maximized - c++

I'm writing an application with Embarcadero RAD 2 Studio (borland) and the owlNext library.
There I create a TDecoratedMDIFrame Object, which I open by using
class TMDIApp : public owl::TApplication { // -------------------------------
public:
TMDIApp() : owl::TApplication(ProgName) {}
TMDIApp(const char far* name, HINSTANCE instance, HINSTANCE prevInstance, const char far* cmdLine, int cmdShow) : owl::TApplication(name, instance, prevInstance, cmdLine, cmdShow) {}
void InitMainWindow();
};
void TMDIApp::InitMainWindow() { // --------------------------
PMAcMDI = new TMAcMDI;
PMW = new TDecoratedMDIFrame(ProgName, MAC_MENU, *PMAcMDI);
MainWindow = PMW;
}
int OwlMain(int, char* []) { // ------------------------
return TMDIApp().Run();
}
So, in the end it get's opened by aplicat.cpp of the owlnext library using MainWindow->ShowWindow(nCmdShow);.
However, Now I want to open it maximized.
I made some research and came upon
PMW->WindowProc(WM_SIZE,SIZE_MAXIMIZED,0);
Which doesn't seem to do anything...
Does anyone of you know how to maximize this window or starting it maximized?

I found information about this problem at an old archive.org copy of the "OWL Programmer's Guide"
http://archive.org/stream/bitsavers_borlandborindowsforCVersion2.0ProgrammersGuideOct9_19152845/Borland_ObjectWindows_for_C_Version_2.0_Programmers_Guide_Oct93_djvu.txt
There it says:
~ ~ You can change how your application's main window is displayed by
Specifying the mam setting the T Application data member nCmdShow,
which corresponds to the ^ / WinMain parameter nCmdShow. You can set
this variable as soon as the Run
function begins, up until the time you call T Application:
:lnitlnstance. This effectively means you can set nCmdShow in either
the InitApplication or InitMainWindow function.
For example, suppose you want to display your window maximized
whenever the user runs the application. You could set nCmdShow in your
InitMainWindow function:
include ttinclude
class TMyApplication : public TApplication { public :
TMyApplication (char far *name) : TApplication (name) {}
void InitMainWindow () ;
1; ■ ■
void TMyApplication: : InitMainWindow () {
SetMainWindow(new TFrameWindow ( , "Maximum Window") ) ; nCmdShow =
SW_SHOWMAXIMIZED;
} int '
OwlMain(int argc> char* argv[]) {
, return TMyApplication("Wow!").Run(); } '
nCmdShow can be set to any value appropriate as ( a parameter to the
ShowWindow Windows function or the TWindow::Shozv member function,
such as SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, and so on.
So, in my case, adding nCmdShow = SW_SHOWMAXIMIZED; inside my InitMainWindow () definition was enough.

Related

How to get Main Window Handle on Page in WinUI 3 Using C++

I am working on a WinUI 3 demo using C++.
I want to get a Main or Native Window Handler to open a Picker within a Page.
The code block which I am using works fine on Window but it does not work on Page.
auto windowNative{ this->try_as<::IWindowNative>()};
winrt::check_bool(windowNative);
HWND hWnd{ 0 };
windowNative->get_WindowHandle(&hWnd);
Help me to get MainWindow Handler in Page1.xaml.cpp
Only Window implements IWindowNative, so you need to pass the window reference around, or if you're sure there's only one Window in your process, you can use a code like this:
HWND GetProcessFirstWindowHandle(DWORD pid = 0)
{
struct ProcessWindow { DWORD pid; HWND hWnd; } pw = {};
pw.pid = pid ? pid : GetCurrentProcessId();
EnumWindows([](auto hWnd, auto lParam)
{
DWORD pid;
GetWindowThreadProcessId(hWnd, &pid);
if (pid != ((ProcessWindow*)lParam)->pid)
return TRUE;
((ProcessWindow*)lParam)->hWnd = hWnd;
return FALSE;
}, (LPARAM)&pw);
return pw.hWnd;
}
And for example, call it simply like this:
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
auto hwnd = GetProcessFirstWindowHandle();
}
You can also add some check on class name, like what's done in this answer (it's C# but the code is already using interop to access native Windows APIs) : Retrive Window Handle in Class Library WinUI3

MFC Debug Assertation Failed!! wincore.cpp Line 972

I have created an MFC Dialog box in a DLL for use in multiple projects and it has functionalities such as:
Getting Listbox data from the main application using the DLL. I can push string data through the main application to the MFC Dialog box but I am getting Assertation errors after compilation.
This process happens in a thread where one thread keeps the Dialog box active and another pushes data as shown in the code below.
void dbox(CDialogClass *dlg)
{
dlg->ShowDlg();
}
void input(CDialogClass *dlg)
{
string str1= "";
while (1)
{
getline(cin, str1);
//cin >> str1;
dlg->SetData(str1);
}
}
int main()
{
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
}
else
{
CDialogClass *dlg = new CDialogClass("Title Dbox",300.0f, 300.0f, 0);
thread t1(input, dlg);
thread t2(dbox, dlg);
t1.join();
t2.join();
}
}
return 0;
}
Here dbox() invokes a ShowDlg function which is in an MFC DLL as below:
void CDialogClass::ShowDlg()
{
dlgg->title = title;
dlgg->dialogWidth = D_width;
dlgg->dialogHeight = D_height;
dlgg->pos = pos;
dlgg->Create(IDD_DIALOG1);
dlgg->ShowWindow(SW_SHOWNORMAL);
dlgg->RunModalLoop();
//dlgg->DoModal();
}
SetData() is called by thread input() and it has the below code in the DLL:
void CDialogClass::SetData(string data)
{
p_text = data;
dlgg->calldata(data);
}
Below is the code for my Dialog class in the DLL just for reference if needed-
#include "stdafx.h"
#include "DlgDisp.h"
#include "afxdialogex.h"
#include "Resource.h"
#include <fstream>
#include <Thread>
IMPLEMENT_DYNAMIC(CDlgDisp, CDialogEx)
CDlgDisp::CDlgDisp(CWnd* pParent /*=NULL*/)
: CDialogEx(CDlgDisp::IDD, pParent)
{
}
CDlgDisp::~CDlgDisp()
{
}
void CDlgDisp::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_listbox);
}
BOOL CDlgDisp::OnInitDialog()
{
//Title manipulations
char *str_title;
str_title = &title[0];
SetWindowText((CAtlString)str_title);
//Size manipulations
CWnd* pctrl = GetDlgItem(IDC_LIST1);
CRect rectctrl;
SetWindowPos(NULL, 0, 0, dialogWidth, dialogHeight, SWP_NOMOVE | SWP_NOZORDER);
pctrl->GetWindowRect(rectctrl);
pctrl->SetWindowPos(NULL, 20, 20, dialogWidth-120, dialogHeight-80, SWP_NOMOVE | SWP_NOZORDER);
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
BEGIN_MESSAGE_MAP(CDlgDisp, CDialogEx)
END_MESSAGE_MAP()
void CDlgDisp::calldata(string strdata)
{
char *str_parameter;
str_parameter = &strdata[0];
CString param = _T("");
param.Format(_T("%s"), (CAtlString)str_parameter);
if (pos == 0)
{
m_listbox.InsertString(0, param);
}
else
m_listbox.AddString(param);
UpdateData(FALSE);
}
the flow of the program for references:
CDlgDisp class is the Dialog class derived from CDialogEx class.
CDialogClass is for interaction with external applications which is derived from CDialog class.
CDialogClass has a public member variable of CDlgDisp class.
external application -> object.CdialogClass -> object.CDlgdisp class
when I execute the program it runs well, and I get an error when I try to input data through the console. It does get printed in the Listbox dynamically but then it shows the Assertation Error.
Here is an image after execution
[enter image description here][1]
and here is the image after I enter the data in console and press enter
[enter image description here][2]
what do you guys think the problem is?
[1]: https://i.stack.imgur.com/pXFMD.png
[2]: https://i.stack.imgur.com/eUXZ7.png
Look into the source where the ASSERT ion take place
You find this comment:
// Note: if either of the above asserts fire and you are
// writing a multithreaded application, it is likely that
// you have passed a C++ object from one thread to another
// and have used that object in a way that was not intended.
// (only simple inline wrapper functions should be used)
//
// In general, CWnd objects should be passed by HWND from
// one thread to another. The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
//
// It is dangerous to pass C++ objects from one thread to
// another, unless the objects are designed to be used in
// such a manner.
MFC window objects use handle maps per thread. This usually doesn't allow you to use the objects for some functions from other threads. It is possible but this is discussed in many other threads.
The way you want to use the MFC isn't possible. Think about synchronisation. If the functions are thread safe that you want to use with the other window you may use SendMessage and the m_hWnd handle directly.
Thank you guys for being first responders to my problem. All the comments were useful and helped me in understanding the problem.
Problem: Since MFC is thread-safe therefore using an object to SetData was creating a memory sharing conflict between both the threads.
Solution: I used a custom message to pass information to be displayed dynamically. Below Links helped completely-
https://blog.csdn.net/xust999/article/details/6267216
On sending end:
::PostMessage(HWND_BROADCAST, WM_UPDATE_DATA, 0, 0);
On receiving end in the header file:
const UINT WM_UPDATE_DATA = ::RegisterWindowMessage(_T("UpdateData"));
Also, in the header file in the Dialog class:
afx_msg LRESULT OnUpdateData(WPARAM wParam, LPARAM lParam);
The above function will be called when the message is posted and all functionalities to be added to it such as-
LRESULT CDlgDisp::OnUpdateData(WPARAM wParam, LPARAM lParam)
{
char *str_parameter;
str_parameter = &parameter[0];
CString param = _T("");
param.Format(_T("%s"), (CAtlString)str_parameter);
if (pos == 0)
{
m_listbox.InsertString(0, param);
}
else
m_listbox.AddString(param);
return 1;
}
Thank you, Everyone.

no instance of overloaded function "strstr" matches the argument list

E0304 no instance of overloaded function "strstr" matches the argument list
I'm getting this error when try to compile, how can i fix this? post the code cus it's better to understand then photo.
So this is the error that i'm getting i don't have any idea what is causing this and how to fix.
int MakeWindows();
int CloseWindows();
int WINAPI WinMain(_In_HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
HW_PROFILE_INFO hwProfileInfo;
const char* cHWID = "{1234-5678-9669-1337}"; //
if (GetCurrentHwProfile(&hwProfileInfo) != NULL) }
printf("Hardware ID: %s\n", hwProfileInfo.szHwProfileGuid);
if (strstr(hwProfileInfo.szHwProfileGuid, cHWID)) {
printf("Your hardware ID was successful\n\n");
Sleep(3069);
system("CLS");
}
else {
printf("Your Hardware ID was denied;\n");
Sleep(1000);
TerminateProcess(GetCurrentProcess(), NULL);
}
}
else {
return 0;
}
};
strstr wants a char* as its first arg. szHwProfileGuid is going to be a wide string. You need wccstr
So try :
const wcchar* cHWID = L"{1234-5678-9669-1337}";
The problem stems from your project being compiled as Unicode ('wide' characters, usually wchar_t types or defined in Windows as WCHAR), and you also using single-byte characters (char or CHAR), for example in your call to strstr().
(As you're seeing here, the two don't cooperate nicely!)
The Windows API defines two versions of many of its structures (and therefore the respective functions that use them), one to accommodate each character type. In your code example, HW_PROFILE_INFO is actually defined as HW_PROFILE_INFOW for the wide-character version of the API, and you're invoking GetCurrentHwProfileW(). This is fine and by design, since your build is instrumented as a Unicode build.
There are a few ways you could fix this; here's a simple method (your original code with two slight modifications):
int MakeWindows();
int CloseWindows();
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
HW_PROFILE_INFOA hwProfileInfo; // <== Change # 1
const char* cHWID = "{1234-5678-9669-1337}"; //
if (GetCurrentHwProfileA(&hwProfileInfo) != NULL) } // <== Change # 2
printf("Hardware ID: %s\n", hwProfileInfo.szHwProfileGuid);
if (strstr(hwProfileInfo.szHwProfileGuid, cHWID)) {
printf("Your hardware ID was successful\n\n");
Sleep(3069);
system("CLS");
}
else {
printf("Your Hardware ID was denied;\n");
Sleep(1000);
TerminateProcess(GetCurrentProcess(), NULL);
}
}
else {
return 0;
}
};
This set of simple changes has you explicitly using the single-byte versions of the WINAPI functions, keeping your call to strstr() consistent for its two arguments.
(I'll mention again that this is only one way to fix this problem, and the "best" solution may be subjective. :))

Get processID using part of WINDOW heading

i use the following program in c++ ,in Visual C++ 6.0, to inform me with message box when the MS Paint program is opened. It uses the exact name of the WINDOW of MS Paint,which is "Untitled - Paint" . However now i need to make the program inform me with message box when i know only a part of the name of the actual WINDOW , for example , if the window is "Abcdefgh - Paint" and i set the string name in this way - std::wstring windowName(L"Paint"); - the program to work again. Using the following 3 rows of code the program works fine when the actual WINDOW name is the exact name of the MS Paint window:
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
But it will not work if the string windowName is just part of the name, i mean if it is "Paint".
Can someone show me how to do this? I thought to take a list of the names of all opened WINDOWS and to compare them with my part of the real name, i mean to search match of the substring "Paint" in their names, but i don't know how to get all opened windows.
Also, this is very important, my computer is old and i am using Visual C++ 6.0, so i can not use all the evolution features of C++ and the program environments nowadays, i mean , i can not use code which is compiled correctly in .NET but does not compiles in Visual C++ 6.0.
Thanks
#include "stdafx.h"
#include < iostream>
#include < string>
#include < windows.h>
#include < sstream>
#include < ctime>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
std::wstring windowName(L"Untitled - Paint");
while(true)
{
Sleep(1000*5);
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
int tday = now->tm_mday;
int tmin = now->tm_min;
int thour = now->tm_hour;
HWND windowHandle = FindWindowW(NULL, windowName.c_str());
DWORD* processID = new DWORD;
GetWindowThreadProcessId(windowHandle, processID);
char probaintstr[20];
sprintf(probaintstr,"%d",*processID);
if(strlen(probaintstr) <=5 )
{
Sleep(1000*10);
MessageBox(NULL,"niama go Notepad ili Wordpad","zaglavie",MB_OK);
}
else {
}
}
return 0;
}
You can use EnumWindows, for example
BOOL CALLBACK enumWindow(HWND hwnd, LPARAM lp)
{
std::string str(512, 0);
int len = GetWindowText(hwnd, &str[0], str.size());
if (str.find("Paint") != std::string::npos)
{
MessageBox(0, str.c_str(), 0, 0);
}
return true;
}
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
EnumWindows(enumWindow, 0);
return 0;
}
Or you can use FindWindowEx and look for classname. The classname for MS Paint is "MSPaintApp". You can find this information from "Spy" utility for windows.
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
for (HWND hwnd = NULL;;)
{
hwnd = FindWindowExA(NULL, hwnd, "MSPaintApp", 0);
if (!hwnd)
break;
std::string str(512, 0);
int len = GetWindowText(hwnd, &str[0], 512);
str.resize(len);
if (str.find("Paint") != std::string::npos)
MessageBox(0, str.c_str(), 0, 0);
}
return 0;
}
For process id you don't need to allocate memory. Just use a reference:
DWORD processID;
GetWindowThreadProcessId(windowHandle, &processID);

c++ WinApi : GetClientRect fails

I am coding a screensaver program running on Windows.
In preview mode, Windows calls the program this way :
Screensaver.exe /p ParentWindowHandle
However, when I make this call in my program :
BOOL res = GetClientRect(parentWindowHandle, rect)
res is FALSE, rect is NULL and I get ERROR_INVALID_WINDOW_HANDLE with GetLastError()
GetWindowRect gives me the same results.
But, if I make a call to BOOL res = IsWindow(parentWindowHandle) instead, I get res == TRUE. Does this not mean I have a valid window handle ?
The code looks like this :
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
unsigned int handle = GetHandleFromCommandLine(pCmdLine); // Custom function (tested and approved :) )
HWND parentWindowHandle = (HWND) handle;
LPRECT rect = NULL;
BOOL res = GetClientRect(parentWindowHandle, rect);
// here, rect == NULL, res == FALSE and GetLastError() returns ERROR_INVALID_WINDOW_HANDLE
// ...
// ...
}
On 64-bit Windows, a window handle is 64 bits and cannot fit in an unsigned int, so your cast is producing a value that is an invalid window handle. You should modify your GetHandleFromCommandLine function so that it returns a proper HWND, not an unsigned int, and no type cast is necessary.
Also, GetClientRect returns the rectangle by storing it into the value pointed at by the second parameter. If you pass it NULL, it has nowhere to store that, so it will either crash or fail with an invalid parameter error. To avoid that, pass in the address of a local variable:
RECT rect;
GetClientRect(..., &rect);