|
Hi all,
I am writing an MFC app for my friend who finds it hard to open the CD ROM drive by pressing the buttons on the CD-DRIVE.
He has 3 drives, and I want individual ones to open by pressing the button Open.
Can I do this?
How?
Thanks
Ashman
PS: Please be detailed, Im rather dumb =)
|
|
|
|
|
You need to use the media control interface (MCI).
You can send strings or commands to the MCI to get things done.
Set CDAudio Door Open
Set CDAudio Door Close
I don't know how to address more than one CD this way.
Its different using the command API rather than the string API.
see also Microsoft knowledge base article: Q109371
Stephen
|
|
|
|
|
-Enter and ESC keys close the dialog how i can stop it .
-How i can load accelerator from resource to MFC\DIALOG
i use loadaccelerator function but it didn't work.
thank you ...
|
|
|
|
|
The best way is to try a keyboard Hook. That we you are totally in control of what's hapenning.
|
|
|
|
|
You stop it by overriding OnOK and OnCancel. You can make the buttons still work by checking the keystate with GetKeyState(VK_RETURN) (or VK_ESCAPE) and returning if they are down. Then your button works, but the key does not.
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|
|
Hi,
I have structure that looks similar to this:
struct MyInfo
{
CString m_str1;
CString m_str2;
COleDateTime m_dtm1;
CString m_str3;
MyInfo(const CString& str1, const CString& str2, const COleDateTime& dtm1, const CString& str3) :
m_str1(str1), m_str2(str2), m_dtm1(dtm1), m_str3(str3)
{ }
bool operator<(const MyInfo& info)
{
return (m_str1 < info.m_str1 ||
m_str2 < info.m_str2 ||
m_dtm1 < info.m_dtm1 ||
m_str3 < info.m_str3);
}
};
I have a map of MyInfo to CString values, like this:
std::map< MyInfo, CString > mapInfo;
I insert/update elements into the map using operator[], like this:
void accumulate(const CString& str1, const CString& str2, const COleDateTime& dtm1, const CString& str3, const CString& strValue)
{
mapInfo[MyInfo(str1, str2, dtm1, str3)] += strValue;
}
Notice that strValue is appended to whatever is already there.
Then later I iterate through every element in the map, but the problem is that I'm getting duplicate entries in the map (for the same MyInfo object). Why?
Thanks,
Alvaro
|
|
|
|
|
...i just tried your code (with slight modifcations to make it compile) and it worked fine, no duplicate entries.
i even did two identical "accumulate" calls in a row, to try to duplicate keys. when i dumped the map, though, the keys were unique.
-c
|
|
|
|
|
I really appreciate you looking into this problem for me Chris! Unfortunately I wasn't expecting to receive a "could not reproduce it" response otherwise I would have taken greater care to avoid it.
Here's how I was able to reproduce this problem. I took my sample code into a new MFC dialog based application I called "Doodle". I added a button to it and then a handler which I called OnButtonTryMap. Then inside I called the (global) accumulate function 100 times to insert/update the same MyInfo objects to the map each time. Here's how it looked:
#pragma warning (disable:4786) // disables: identifier was truncated to '255' characters in the debug information
#include <map>
struct MyInfo
{
CString m_str1;
CString m_str2;
COleDateTime m_dtm1;
CString m_str3;
MyInfo(const CString& str1, const CString& str2, const COleDateTime& dtm1, const CString& str3) :
m_str1(str1), m_str2(str2), m_dtm1(dtm1), m_str3(str3)
{ }
bool operator<(const MyInfo& info) const
{
return (m_str1 < info.m_str1 ||
m_str2 < info.m_str2 ||
m_dtm1 < info.m_dtm1 ||
m_str3 < info.m_str3);
}
};
std::map< MyInfo, CString > g_mapInfo;
const COleDateTime g_dtmCurrent = COleDateTime::GetCurrentTime();
void accumulate(const CString& str1, const CString& str2, const COleDateTime& dtm1, const CString& str3, const CString& strValue)
{
g_mapInfo[MyInfo(str1, str2, dtm1, str3)] += strValue;
}
void CDoodleDlg::OnButtonTryMap()
{
CString str1, str2, str3;
COleDateTime dtm = g_dtmCurrent;
for (int iItem = 0; iItem < 100; iItem++)
{
str1.Format("str1 = %d", iItem);
str2.Format("str2 = %d", iItem + 1);
str3.Format("str3 = %d", iItem + 2);
dtm += 1;
accumulate(str1, str2, dtm, str3, str1);
}
CString strMessage;
strMessage.Format("There are %d items in the map.", g_mapInfo.size());
AfxMessageBox(strMessage);
}
Try this and see if you get the same results. The first time I press the button I get "100 items" in the message. The second time, I get 118! The third time I get 142, then 154, and so on. If I've done this correctly, I should always see 100 items, shouldn't I?
Thanks for your help,
Alvaro
|
|
|
|
|
You hit the nail on the head! It's the ambiguous comparison that's causing the problem. How could I have been so blind? I changed the less-than operator to this and now it works as expected:
bool operator<(const MyInfo& info) const
{
return ((m_str1 < info.m_str1) ||
(m_str1 == info.m_str1 && m_str2 < info.m_str2) ||
(m_str1 == info.m_str1 && m_str2 == info.m_str2 && m_dtm1 < info.m_dtm1) ||
(m_str1 == info.m_str1 && m_str2 == info.m_str2 && m_dtm1 == info.m_dtm1 && m_str3 < info.m_str3));
}
Thanks for your help!
Alvaro
|
|
|
|
|
the problem is in your operator < function.
if MyInfo a = {"E", "A", xxx, xxx} MyInfo b = {"A", "E", xxx, xxx}
a will always be less than b; and b will always be less than a. but std::map requires that the comparison is strict. a < b or b < a, not both.
there's a good chance the ambiguous comparison is screwing with the map's tree.
-c
|
|
|
|
|
Chris,
In this example you're right because str1 is different for every element in the map. But what if str1 where not always different? If str1 were sometimes the same value as in previous elements then the solution you propose would not work. In other words, if in the for loop you put:
str1 = "a";
instead of
str1.Format("str1 = %d", iItem);
then we would still have 100 unique items but your solution would yield only 1. So the problem does not appear to be in the less-than operator. It's something else which too me smells like a bug in the std::map code.
Anyone have a clue?
Thanks,
Alvaro
|
|
|
|
|
Hi
Does anyone know how to open up a dialog resource from a DLL? I am using LoadLibrary to load DllA.dll which contains IDD_DIALOGA resource. Then find the resource handle by using FindResource and LoadResource functions. However, I don't know what to do with the return value from LoadResource. Does anyone know if there is a way to open up IDD_DIALOGA resource from that handle in the client application?
VERIFY(hModule = ::LoadLibrary("DllA.dll"));
HRSRC hDialogA = ::FindResource(hModule, "#7000", RT_DIALOG);
LPVOID lpvResource = (LPVOID) ::LoadResource(hModule, hDialogA);
Thanks alot for your time!
kk9
|
|
|
|
|
I use the following:
HINSTANCE h = (HINSTANCE)::GetModuleHandle(pszDllName);
ASSERT(h);
HINSTANCE hPrevious = AfxGetResourceHandle();
AfxSetResourceHandle(h);
// Do your Processing here
if(hPrevious)
AfxSetResourceHandle(hPrevious);
|
|
|
|
|
I want to maximise window from SystemTray.
after calling DrawAnimatedRects for my window
I tried to use SetActiveWindow();
SetForegroundWindow();
and even ModifyStyleEx(0,WS_EX_TOPMOST)
and it works in WinNT but not Win2000
can anybody help me?
Mike.
|
|
|
|
|
Does GetLastError() give any valueable information?
Are you sure this is caused by DrawAnimatedRects()? Have you considered commenting out the DrawAnimatedRects-call and see what happens?
From what function do you call DrawAnimatedRects()?
--
Alex Marbus
|
|
|
|
|
thank you for response.
GetLastError() tell me that all OK.
really problem doesn't caused by DrawAnimatedRects()
I tried to prevent restricting for SetForegroundWindow (as MSDN tells) but I can't do it
If it is interesting for you, I solved my problem, using
SetWindowPos(&CWnd::wndTopMost...); and then SetWindowPos(&CWnd::wndNoTopMost...);
Mike.
|
|
|
|
|
Win 2K (and 98) restrict when SetForegroundWindow() can be used. Read the docs page for SetForegroundWindow() - it has all the details.
--Mike--
http://home.inreach.com/mdunn/
Is history an illusion caused by the passage of time, or is time an illusion caused by the passage of history?
|
|
|
|
|
thank you for response.
I tried to prevent restricting for SetForegroundWindow (as MSDN tells) but I can't do it
If it is interesting for you, I solved my problem, using
SetWindowPos(&CWnd::wndTopMost...); and then SetWindowPos(&CWnd::wndNoTopMost...);
Mike.
|
|
|
|
|
What is the difference btw. these two approaches, theoretically?
Practically they seem to be equivalent. Yep?
Which one to use when?
CMyClass::CMyClass(int i)
:m_int(i),
m_str(NULL)
{}
and
CMyClass::CMyClass(int i)
{
m_int = i;
m_str = NULL;
}
|
|
|
|
|
That would depend on what types the varriables are.
CMyClass::CMyClass(int i)
{
m_int = i;
m_str = NULL;
}
Is going to call the default constructors on all member varriables then do the assignments, while
CMyClass::CMyClass(int i) :m_int(i), m_str(NULL) {}
Calls the appropriate constructors first then does teh assignment.
For basic types there'll be little (if any) difference, but for UDT there could be significant overhead in a default constructor or assignment operator.
|
|
|
|
|
er...make that
Calls the appropriate constructors first then does not need to do assignments.
|
|
|
|
|
i've the following problem. i'd like to create a folder on my DNS server and share it only to selecte users. for example i'd like to create a folder named BEckhard an then share it. Only the user BEckhard and the group of Administrators should have rights for this folder. (example: BEckhard is only allowed to create files). The users are stored in the active directory (win2000 server). creating the folder isn't the problem but sharing it seems to be impossible :*-(( please could you give me a code example for sharing a folder for a specific user.
thanks
benedikt
|
|
|
|
|
Here is asample of sharing the directory.
#define FORCE_UNICODE
#include <windows.h>
#include <stdio.h>
#include <lm.h>
#pragma comment ( lib, "Netapi32.lib")
void wmain( int argc, TCHAR *argv[ ])
{
NET_API_STATUS res;
SHARE_INFO_2 p;
DWORD parm_err = 0;
if(argc<2)
printf("Usage: NetShareAdd server\n");
else
{
p.shi2_netname = (unsigned short *)TEXT("TESTSHARE");
p.shi2_type = STYPE_DISKTREE;
p.shi2_remark = (unsigned short *)TEXT("TESTSHARE to test NetShareAdd");
p.shi2_permissions = 0;
p.shi2_max_uses = 4;
p.shi2_current_uses = 0;
p.shi2_path = (unsigned short * )TEXT("C:\\");
p.shi2_passwd = NULL;
res=NetShareAdd((unsigned short *)argv[1], 2, (LPBYTE) &p, &parm_err);
if(res==0)
printf("Share created.\n");
else
printf("Error: %u\tparmerr=%u\n", res, parm_err);
}
return;
}
In this sample the Level of sharing is 2.
In your case where you want to restrict the sharing to specific users you need to modifiy the info structure to pass it
a pointer to SHARE_INFO_502 structure instead of SHARE_INFO_2. after you define the PSECURITY_DESCRIPTOR for it.
Hope this might help
cheers
Alfadhly
|
|
|
|
|
thank you for your example. i tried to work with the PSECURITY_DESCRIPTOR, but it's a little bit difficult. would it be possible to gife me an example of sharing a folder (lets say "Benedikt") for the user "BEckhard"? isn't it possible to use the netshare functions like in the console. it would be much more easier.
thanx
benedikt
|
|
|
|
|
Hi,
Why is it diffecult to use the PSECURITY_DESCRIPTOR
Steps are as follow
1) get the required size to hold Sid associated with the supplied user "BEckhard" using LookupAccountNameW it will be returned in the 4th parameter of the LookupAccountNameW function
2) Now that you have the size get the Sid associated with the supplied user "BEckhard" using LookupAccountNameW again
3)Add the required access to the PSID using AddAccessAllowedAce
4) Initilize a new SID
5) set the information in a discretionary access-control (SetSecurityDescriptorDacl)list in the new Sid using the SID you got in setp 2
6) Now set up the share information in the SHARE_INFO_502 structure and set the "si502.shi502_security_descriptor" to the one you set in step 5 , and si502.shi502_path to "The full path of Benedikt directory"
7) Finally call NetShareAdd to add the share on the
Hope this might help
Cheers
Alfadhly
|
|
|
|