|
you C class does not have a constructor with 2 parameters.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
Actually class C constructor should have had four (Yes, 4 , since it contains four variables) parameters. Anyway...
Try
#include <iostream>
using namespace std;
class A
{
public:
int a;
A(int a):a(a){}
};
class B: public A
{
public:
int b;
B(int a, int b): A(a), b(b){}
};
class C: public B
{
public:
B obj;
C(int a, int b): B(a, b), obj(b, a){} friend ostream & operator << (ostream & os, const C & c); };
ostream & operator << (ostream & os, const C & c)
{
os << "a = " << c.a << ", b = " << c.b << ", obj.a = " << c.obj.a << ", obj.b = " << c.obj.b;
return os;
}
int main()
{
C obj1(10,20);
cout << obj1 << endl;
}
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
Some of my employer's customers have old Windows-computers (some are from the 90's) and they are not allowed to connect to the Internet and they have no Service Packs or Frameworks installed. I need to write a simple GUI application that does some UART-communication that can run on these old computers and I would greatly appreciate some advice.
1. What API would you recommend I use? I've heard of an API called "Win32", is that the one I should use?
2. What GUI library would you recommend I choose?
3. Can I program in C++ or am I restricted to C?
4. Is Visual Studio 2005 a good choice for an IDE or would you recommend something else?
5. Anything else I need to be aware of?
|
|
|
|
|
- Win32 API
- VC++ MFC application
- C++
- VC++6.0
|
|
|
|
|
1. What API would you recommend I use? I've heard of an API called "Win32", is that the one I should use? Most probably. At that time there weren't many other choices.
2. What GUI library would you recommend I choose? You don't necessarily need a GUI library. Win32 was quite capable of making a simple GUI app.
3. Can I program in C++ or am I restricted to C? You can use C++.
4. Is Visual Studio 2005 a good choice for an IDE or would you recommend something else? VS 2019 is WAY better and you can target 32-bit Win32 applications.
5. Anything else I need to be aware of? Link everything statically. You don't want to depend on runtime DLLs. Keep it simple, keep it small.
Mircea
|
|
|
|
|
|
arnold_w wrote: (some are from the 90's) What is exactly the lowest specification without being that vague?
arnold_w wrote: 1. What API would you recommend I use? I've heard of an API called "Win32", is that the one I should use? There's no other real option.
arnold_w wrote: 2. What GUI library would you recommend I choose? Win32, native. It is recogniazable and works well with accessability features.
arnold_w wrote: 3. Can I program in C++ or am I restricted to C? I restrict you to Delphi. Lots simpeler than C++, makes you more productive.
arnold_w wrote: 4. Is Visual Studio 2005 a good choice for an IDE or would you recommend something else? It is, for non-Delphi apps.
arnold_w wrote: 5. Anything else I need to be aware of? If you need to ask what language, you're not up to the task. Run.
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
arnold_w wrote: 5. Anything else I need to be aware of? |
poor you.
your only choice is win32.
I suggest setting up a virtual machine with the target OS (if it's possible) on which you can do your work (install VS2005... )
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
I'm trying to determine this value for a system-status program that I maintain.
In the past, I've just shown Uptime, but now that I'm forced to Windows 10, that isn't entirely informative!! If I log out of my machine (shutdown -l) and then log back in, Uptime doesn't get reset. So I want to add an option to show logon time vs reboot time (Uptime)... but I'm not having much success with this...
I have found several articles which recommend NetUserGetInfo(), but this is returning invalid data for me... for example, I just logged out, and back in, to my machine... here is the code, followed by the results that I get:
dwLevel = 2;
wchar_t username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserNameW(username, &username_len);
nStatus = NetUserGetInfo(NULL, username, dwLevel, (LPBYTE *) & pBuf);
pBuf2 = (LPUSER_INFO_2) pBuf;
wprintf(L"User account name: %s\n", pBuf2->usri2_name);
wprintf(L"Password age (seconds): %d\n", pBuf2->usri2_password_age);
wprintf(L"Last logon (seconds since January 1, 1970 GMT): %d\n", pBuf2->usri2_last_logon);
time_t logon_time = pBuf2->usri2_last_logon ;
char buff[20];
strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&logon_time));
printf("logon time: %s\n", buff);
The results that I get are:
User account name: dan7m
Password age (seconds): 10221317
Last logon (seconds since January 1, 1970 GMT): 1616249786
logon time: 2021-03-20 07:16:26
Note that the logon time *actually* around 1920 on 06/05/21...
So I have two questions, I guess...
1. is there some way to make this function actually work??
2. if not, how else can I programmatically access the login time on Windows 10 64bit??
|
|
|
|
|
Derell Licht wrote: wprintf(L"Password age (seconds): %d\n", pBuf2->usri2_password_age);
wprintf(L"Last logon (seconds since January 1, 1970 GMT): %d\n", pBuf2->usri2_last_logon); Not sure if it's related or not, but the two members that are being printed here are DWORD s so you might want to use %lu instead.
Other than that, are you running into a timezone issue?
I tried your code on my Windows 10 system and it reported the correct numbers.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
modified 7-Jun-21 10:29am.
|
|
|
|
|
Okay, I changed them to %u, which made no difference. I'm using a 32-bit compiler, so I don't need to specify %lu to get 32-bit values.
This is definitely *not* a timezone issue, since the logon time is off by 77 days, not by 8 hours!!
|
|
|
|
|
BTW, I found another site which suggested a console command to display last logon:
> net user dan7m | findstr /B /C:"Last logon"
Last logon 03/20/21 07:16:26
Interestingly, that is showing exactly the same logon time as NetUserGetInfo(2) is showing...
But that is *not* when I last logged on; it's not even when I last rebooted - Uptime is showing 4.5 days, which is correct...
I think, maybe, this suggests that the 'logon' time that I'm actually looking for - which is the time since I last logged out of this session and logged in again... is maybe called something else entirely in Windows 10??
I am very confused by all this...
|
|
|
|
|
Hi,
The NetUserGetInfo function is an old derelict function. (pun intentional) Maybe you could use the Security and Identity[^] framework to get session information.
Disclaimer: This is a code sample, it doesn't handle dynamic daylight saving time. Also, the pointer arithmetic could be refactored.
#pragma comment(lib, "Secur32.lib")
#include <iostream>
#include <windows.h>
#include <ntsecapi.h>
INT main()
{
DWORD lc = 0;
DWORD status = 0;
PLUID list = nullptr;
LsaEnumerateLogonSessions(&lc, &list);
for (DWORD i = 0; i < lc; i++)
{
PSECURITY_LOGON_SESSION_DATA pData;
status = LsaGetLogonSessionData((PLUID)((INT_PTR)list + sizeof(LUID) * i), &pData);
if (0 == status)
{
if (Interactive == pData->LogonType)
{
FILETIME ft;
SYSTEMTIME st_utc, st_local;
TIME_ZONE_INFORMATION tzi;
ft.dwHighDateTime = pData->LogonTime.HighPart;
ft.dwLowDateTime = pData->LogonTime.LowPart;
GetTimeZoneInformation(&tzi);
FileTimeToSystemTime(&ft, &st_utc);
SystemTimeToTzSpecificLocalTime(&tzi, &st_utc, &st_local);
wprintf(L"UserName: %s\n", pData->UserName.Buffer);
wprintf(L"Last logon %s: %d/%d/%d-%d:%d:%d:%d\n", tzi.StandardName, st_local.wMonth, st_local.wDay, st_local.wYear, st_local.wHour, st_local.wMinute, st_local.wSecond, st_local.wMilliseconds);
}
LsaFreeReturnBuffer(pData);
}
}
}
I noticed that the C# guys have much better time zone tools[^]. For some reason nobody invested any time into doing this for the public native API.
So I whipped up something real quick for converting to an arbitrary time zone:
typedef struct _REG_TZI_FORMAT
{
LONG Bias;
LONG StandardBias;
LONG DaylightBias;
SYSTEMTIME StandardDate;
SYSTEMTIME DaylightDate;
} REG_TZI_FORMAT;
BOOL ConvertToTzSpecificTimeZone(const wchar_t time_zone[], TIME_ZONE_INFORMATION * tzi, const SYSTEMTIME * lpUniversalTime, const LPSYSTEMTIME lpLocalTime)
{
HKEY k;
DWORD size = 0;
REG_TZI_FORMAT tzdb;
BOOL bRet = FALSE;
SecureZeroMemory(tzi, sizeof(tzi));
LSTATUS status = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", &k);
if (ERROR_SUCCESS == status)
{
size = sizeof(REG_TZI_FORMAT);
status = RegGetValueW(k, time_zone, L"TZI", RRF_RT_REG_BINARY, 0, &tzdb, &size);
if (ERROR_SUCCESS == status)
{
tzi->Bias = tzdb.Bias;
tzi->DaylightBias = tzdb.DaylightBias;
tzi->DaylightDate = tzdb.DaylightDate;
tzi->StandardBias = tzdb.StandardBias;
tzi->StandardDate = tzdb.StandardDate;
wcscpy_s(tzi->StandardName, time_zone);
bRet = SystemTimeToTzSpecificLocalTime(tzi, lpUniversalTime, lpLocalTime);
}
RegCloseKey(k);
}
return bRet;
}
You would use it something like this:
if (ConvertToTzSpecificTimeZone(L"Tokyo Standard Time", &tzi, &st_utc, &st_local))
{
wprintf(L"Last logon %s: %d/%d/%d-%d:%d:%d:%d\n", tzi.StandardName, st_local.wMonth, st_local.wDay, st_local.wYear, st_local.wHour, st_local.wMinute, st_local.wSecond, st_local.wMilliseconds);
}
Best Wishes,
-David Delaune
edit: added call to RegCloseKey
modified 6-Jun-21 14:30pm.
|
|
|
|
|
Hey, @Randor, that works *great* !!!!!!!!!!! Thank you so much!!
I do have *one* minor issue with it, though...
Is this intended to be a 64-bit-only operation??
I use MinGW, not Visual C++, for all of my app development, and at this point, I still use a 32-bit compiler... However, I cannot build this with 32-bit MinGW:
> g++ -Wall -O2 login_lsa.cpp -o login_lsa.exe -lsecur32
login_lsa.cpp: In function 'INT main()':
login_lsa.cpp:14: error: 'LsaEnumerateLogonSessions' was not declared in this scope
login_lsa.cpp:17: error: 'PSECURITY_LOGON_SESSION_DATA' was not declared in this scope
login_lsa.cpp:17: error: expected ';' before 'pData'
login_lsa.cpp:19: error: 'pData' was not declared in this scope
login_lsa.cpp:19: error: 'LsaGetLogonSessionData' was not declared in this scope
I searched through *all* .h and .hpp files in c:\mingw, and these functions were not declared anywhere...
Mind ye, it *does* build and run just fine with 64-bit MinGW.
(in case anyone is not familiar with MinGW, it stands for Minimal Gnu for Windows, and is a port of the GNU toolchain to Windows, using Windows libraries for most services.)
My MinGW 32-bit toolchain *does* have netsecapi.h and secur32.lib (in its format), but these LSA functions appear to not be included...
I also tried current TDM build of MinGW, which is gcc 10.3.0, but it does not contain these functions either...
|
|
|
|
|
Derell Licht wrote: Is this intended to be a 64-bit-only operation??
Not sure what gave you that idea. That code will build and function correctly on both 32/64 bit platforms. The library 'Secur32.lib' was named a really long time ago and just like the path'C:\Windows\System32' the decision was made to keep the old name.
Derell Licht wrote: I searched through *all* .h and .hpp files in c:\mingw, and these functions were not declared anywhere...
I very rarely use the MinGW compiler tools. The errors you are getting are simple #include errors. I checked the msys2 source code repository and found mingw-w64/ntsecapi.h which is dated Dec 13, 2013 has all of the required function declarations.
Sounds like you just need to update your development environment.
Best Wishes,
-David Delaune
|
|
|
|
|
Ahhh!! So you *are using 64-bit compiler then ?!?!
mingw-w64 is the 64-bit compiler... and in my 64-bit compiler, they are also present, but not in the 32-bit compiler...
Actually, though, I found a way to make this work with Mingw32...
I found the clue in a page for gkrellm application, which has a support file to add support for system functions which are missing in default MinGW-32 package...
What he did is use LoadLibrary() to load and obtain a handle for secur32.dll,
then used GetProcAddress() to get pointers to the required functions:
hSecur32 = LoadLibraryW(L"secur32.dll");
if (hSecur32 != NULL)
{
pfLELS = (pfLsaEnumerateLogonSessions)GetProcAddress(hSecur32, "LsaEnumerateLogonSessions");
if (pfLELS == NULL)
{
wprintf(L"Could not get address for LsaEnumerateLogonSessions() in secur32.dll\n");
}
That worked beautifully for me!!
And yes, your code *does* in fact return the login times that I was looking for; Thank You again!!
|
|
|
|
|
Derell Licht wrote: That worked beautifully for me!!
And yes, your code *does* in fact return the login times that I was looking for; Thank You again!!
You are welcome.
Best Wishes,
-David Delaune
|
|
|
|
|
Well, since this works so nicely, I thought I would include the complete, working demo function here... however, apparently, I cannot actually attach a file in a message, so I will just link to the file in my Github repository, in the program that it will be used in.
derbar/login_lsa.cpp at master · DerellLicht/derbar · GitHub[^]
Be sure to enable the STAND_ALONE macro to build stand-alone utility, either in the code, or by putting the macro on the command line, like this:
g++ -Wall -O2 -DSTAND_ALONE=1 login_lsa.cpp -o login_lsa.exe -lsecur32
It works very nicely!!
|
|
|
|
|
|
Actually, that's a good idea... I haven't created an article here in awhile...
I did so... here is a link to the article:
Determine Time Since Last Logon[^]
modified 8-Jun-21 10:11am.
|
|
|
|
|
thanks for sharing that.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
Declare a structure "Student" which contains the following information:
1
i.
ii.
Student ID
Grade for 5 subjects
2. Write a function to
i
search for a Student ID and if exists write "Found", otherwise, write "Not Found"
Write the Student found (ID and Grade) to a file with file name "StudentFile.txt
In the main (0 function:
3.
i
ii.
ii.
Read the data of an array of 10 students from the user (i.e., keyboard)
Read from the user a student ID to search for
Invoke the function search to search for the Student ID read by the user
|
|
|
|
|
Well, it likes like your homework. But what is your "urgent question"?
|
|
|
|
|
|
MAHMOUD ALI Jun2021 wrote: DO YOU KNOW ANSWER ??
To WHAT question?
|
|
|
|
|