|
This is my first post here, or on any coding forum in fact. Before now I've always eventually been able to solve/explain/get around problems after some amount of banging my head against the wall. This though has me stumped, so if anyone can tell me what might be happening here I would be incredibly grateful since my project is stuck until I solve this, and I've pretty much given up.
I'll put the fundamental problem/question first since the rest of the information may be irrelevant. Basically, at a certain point in the execution of my code, the Win32 API call SendMessage() is returning 0, with GetLastError() also returning 0, yet the message is not being passed to the target window's WindowProc. I've tested by putting a breakpoint in the WindowProc (it't the right one, and execution is passing through there before and after this particular point, for the exact same window). I've also confirmed using Spy++, which again does not detect the sent message. I originally found the problem because WM_SIZE was not being received after calling SetWindowPos() with a new size, and through testing with Spy++ I found that WM_WINDOWPOSCHANGING(ED)/WM_NCCALCSIZE etc were being generated, but not WM_SIZE, despite the fact that the window size HAD changed. I temporarily got around it by simply doing my processing in response to WM_WINDOWPOSCHANGED instead of WM_SIZE, but then the problem appeared again when I send a user defined message to the window to ask it for it's requested size. The bottom line is that at this point in execution, SendMessage() is apparently doing nothing, even if I just try to send a WM_NULL message, it isn't delivered, Spy++ doesn't detect it even when the hook scope is all windows of the process. Does anyone know of any situation that can cause SendMessage() to silently fail to deliver its message to the destination window procedure?
A bit more info. I'm using native C++ and WTL, but the problem is related to the calls to the Win32 API, the WTL/ATL code is not relevant I'm pretty sure. I have some custom written window classes (derived from ATL::CWindowImpl) for my GUI, which act as containers and handle automatic positioning/resizing of their children when they are resized themselves, and send a message to their parent whenever they require resizing. In a certain case in my program I have a number of such windows nested within each other, and at one point when I expand a certain one, causing a series of messages to be sent up and down the parent/child chain, the above problem is occurring. Is there some kind of limit on the number of times a window procedure can be called recursively on the stack? On the number of sent messages a particular window can be processing at one time? There's definitely no logical error causing infinite recursion, the nesting is not extreme, perhaps about 15 child windows deep, if that. I'm simply starting at the base, requesting desired size information from the direct children (which they obtain recursively), then calling SetWindowPos() to resize them, and in response to the messages generated from this call, the child windows are then doing the same procedure themselves on their own child windows.
If anyone has any suggestions at all on what could be causing this, please let me know. I've run out of ideas, and patience. Thanks.
|
|
|
|
|
How can I display a message box that would disappear automatically on certain condtion.. I am not sure if I need a timer.... like the following code example
while( ! flag)
{
// I would like to show a message box here that will display as long as flag !=0 and disappear automatically when flag = 1;
if(condition)
flag = 1;
}
|
|
|
|
|
sabdalla80 wrote: How can I display a message box that would disappear automatically on certain condtion..
By reading here.
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
Wow, you are fast. Excellent !
|
|
|
|
|
The example shows how to pop up the message by clicking, how can I make it pop up under a condition without actually clicking on anything?
Thanks
|
|
|
|
|
What value did you use for the third argument to MessageBox() ?
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
I passed a NULL. After looking at the code, I think I know what to do...All I need to know was how and when to use WM_CLOSE.
I appreciate your help.
|
|
|
|
|
sabdalla80 wrote: I passed a NULL.
Why would you pass NULL when it expects a bool ? In any case, since NULL resolves to 0 , the MessageBox() function will treat that as false .
bclose - If this is set to true, the message box will close on its own after the delay period, otherwise the OK button is enabled so that the user can dismiss the message box manually.
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
Hi,
I am trying to get the logged on user info from 'Win32_LogonSession' Class. However when I try to get the 'Name' field from this Class I am getting NULL value in variable 'vtProp' at below line .
pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
Below is the code snippet.
==================
HRESULT hres = WBEM_S_NO_ERROR;
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT Name FROM Win32_LogonSession WHERE LogonType = 10"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (FAILED(hres))
{
//cout << "Query for operating system name failed."
// << " Error code = 0x"
// << hex << hres << endl;
pSvc->Release();
pLoc->Release();
return 1; // Program has failed.
}
IWbemClassObject *pclsObj;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
ErrorInfo(hres,11);
break;
}
VARIANT vtProp;
// Get the value of the Name property
hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
printf(" Logged On User Name : %s",vtProp.bstrVal);
VariantClear(&vtProp);
}
====================
Regards,
Supriya Tonape.
modified on Wednesday, October 22, 2008 3:54 PM
|
|
|
|
|
Strange. I couldn't get any of the fields to return a non-null value. Can you use GetUserName() instead?
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
'GetUserName' returns user associated with the current thread only. I wanted to run my program on any host machine and get all usernames who are logged on that host machine n has active sessions...
|
|
|
|
|
Supriya Tonape wrote: I wanted to run my program on any host machine and get all usernames who are logged on that host machine...
Can you use NetWkstaUserEnum() ?
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
Thanks but my requirement is that I have to get these names through WMI only. In fact after you told I tried API NetWkstaUserEnuma() and got Usernames too! but I donno whats gng wrong to not give me results...
|
|
|
|
|
any idea how can I get the username from {Win32_LogonSession.LogonId="50493851"} ? I am getting this though! I guess there shud be some way by using this ID I can get the required name. any suggestion ?
|
|
|
|
|
Supriya Tonape wrote: any idea how can I get the username from {Win32_LogonSession.LogonId="50493851"} ?
Try:
#include <ntsecapi.h>
#pragma comment(lib, "Secur32.lib")
...
LUID luid;
luid.HighPart = 0;
luid.LowPart = 50493851;
PSECURITY_LOGON_SESSION_DATA pLogonSessionData;
if (0 == ::LsaGetLogonSessionData(&luid, &pLogonSessionData))
{
::LsaFreeReturnBuffer(pLogonSessionData);
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thx Mark but I wanna use these APIs(Win32_LogonSession,Win32_LoggedOnUser etc) only so it will be gr8 help if you can tell me how to get my required info thru them...
Any idea how to use "Win32_LoggedOnUser.Antecedent" when I have 'LoginID' of user ?
Regards,
Supriya Tonape
|
|
|
|
|
Here's some C# that lists the interactive sessions - you should be able to extract the right queries from this...
ManagementObjectSearcher logonsessionsearcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogonSession Where LogonType = 2 OR LogonType = 10");
foreach (ManagementObject logonsession in logonsessionsearcher.Get())
{
Console.WriteLine("LogonId: {0}", logonsession["LogonId"].ToString());
Console.WriteLine("LogonType: {0}", logonsession["LogonType"].ToString());
ManagementObjectSearcher associationsearcher = new ManagementObjectSearcher("Associators of {Win32_LogonSession.LogonId=" + logonsession["LogonId"].ToString() + "} Where AssocClass=Win32_LoggedOnUser Role=Dependent");
foreach (ManagementObject association in associationsearcher.Get())
{
Console.WriteLine(" Name: {0}", association["Name"].ToString());
Console.WriteLine(" Domain: {0}", association["Domain"].ToString());
}
Console.WriteLine("");
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thx Mark I will see how I can do this in C++.
I guess we cant use this "Associators of {Win32_LogonSession.LogonId=" etc. in C++ so I need
to check out the way how i can accomplish it in C++... I am not getting that though and
tried multiple queries/combinations in C++ already... will check..
I am though.
Regards,
Supriya Tonape.
|
|
|
|
|
How do you do WMI queries in C++? I've always used .NET like shown
which is the same in C++ or C#.
The query should be the same in native C++ I would think...
Associators of {Win32_LogonSession.LogonId=50493851} Where AssocClass=Win32_LoggedOnUser Role=Dependent
where 50493851 is the logon session ID (insert an actual ID)
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I just looked at this link
Example: Getting WMI Data from the Local Computer[^]
and it looks like query text just like I used.
The "while (pEnumerator) " loop is the same as my foreach loop.
Where's the problem?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes I am using the same for looping. But I am not getting 'Name'field when I query diretly to 'Win32_LogonSession'class. There is some other way for it.. I am new to WMI stuff.. thru Win32_LoggedOnUser i shud get it but I am exploring it...I will try the query you had given me above..
Regards,
Supriya Tonape
|
|
|
|
|
Nope that query is not working. I am getting 'Win32_LogonSession.LogonId' after executing query : "SELECT * FROM Win32_LogonSession WHERE LogonType = 2 OR LogonType = 10"
what are next steps ? (in C++)
Regards,
Supriya Tonape
|
|
|
|
|
Supriya Tonape wrote: I am getting 'Win32_LogonSession.LogonId'
I thought you were already able to get the LogonId and you needed
to get the name?
To get the user name from the Win32_LoggedOnUser class, you need to do the
second query I showed you using the LogonId from the query you've already done.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes I am getting LogonId ! Second query is not working for me...
Regards,
Supriya Tonape
|
|
|
|
|
What does the code look like?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|