|
Hi Developers,
I want to map the short cut keys like F1-F12 with some functionality. I have made entry in accelerator table for those keys with the respective menu IDs( which in turn mapped with the desired functions).
The problem i am facing is, it works only if any view is currently open/active, otherwise not.
Can anyone help me out.
Thanks.
Amrit Agrawal
Software Developer.
|
|
|
|
|
Function keys (or any keys) are only delivered to the Window that has the focus, that is the active window.
|
|
|
|
|
Have a look at RegisterHotKey[^].
Independent ACN Business Owner- Check out the possibilities for your future!
- Financial independance
- Full time or Part time
- In more than 20 countries through North America, Europe, Asia and the Pacific
- Featuring the ACN IRIS 5000 video phone. See the person you are talking to.
Within you lies the power for good - Use it!
|
|
|
|
|
Dear all,
I am facing a weird problem and I need your help. I have an MFC MDI application, and I am trying to create a WPF Window as a child of the opened CView.
I was able to successfully do that by handling the OnCreate message in my CView, and creating the WPF window. I also set the CView to be the parent of the WPF window so it behaves as its child.
Here is what I did:
int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
m_windowWrapper.Create(this->GetSafeHwnd());
return 0;
}
void CMyWindowWrapper::Create(HWND hParent)
{
m_myWindow = gcnew MyWindow();
m_myWindow->Show();
IntPtr^ hChildWnd = m_myWindow->GetHwnd();
::SetParent((HWND)hChildWnd->ToPointer(), hParent);
}
public partial class MyWindow : Window
{
public MyWindow()
{
InitializeComponent();
MouseLeftButtonDown += (o, e) => DragMove();
}
public IntPtr GetHwnd()
{
return (new System.Windows.Interop.WindowInteropHelper(this)).Handle;
}
}ndows.Interop.WindowInteropHelper(this)).Handle;
}
}
The WPF window appear as expected. Now the problem happens when I try to resize the WPF window. Suddenly the controls inside the window are streched and re-positioned as if the new size of the WPF window is the size of the parent CView! I tried to handle the SizeChanged event, and found that the NewSize was much larger than the size of the WPF window and was most probably the size of the containing CView.
I tried to remove the SetParent call, and the resizing worked correctly. I wonder what is going wrong in resizing and WPF window whose parent is a CView.
I uploaded a sample application illustrating the problem:
http://cid-a059807de2e23c43.office.live.com/self.aspx/.Public/ResizeProblem.zip
Please help me.
Thank you.
modified 6-Oct-11 10:01am.
|
|
|
|
|
I think you need to implement something in the WPF window analogous to what is described here[^].
I'm not versed in WPF.
You also might need to add ON_WM_SIZE() to your message map in the view class and then the following code:
void CMFCApplicationView::OnSize(UINT nType, int cx, int cy)
{
m_windowWrapper.OnSize(nType, cx, cy);
CView::OnSize(nType, cx, cy);
}
and the following code in MyWindowWrapper:
void CMyWindowWrapper::OnSize(UINT nType, int cx, int cy)
{
IntPtr^ hChildWnd = m_pMembers->m_myWindow->GetHwnd();
::SetWindowPos((HWND)hChildWnd->ToPointer(), 0, 0, 0, cx, cy, SWP_NOMOVE | SWP_ASYNCWINDOWPOS | SWP_NOZORDER);
}
Good luck!
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Thank you Ahmed for your reply
I think the way you described makes the WPF window always having the size of the CView whenever the view gets resized. This is not what I am trying to do. My problem is that whenever I try to resize the WPF window, its controls suddenly get expanded and repositioned as if the new size of the WPF window is the size of the view!
This is really a strange problem. You can just run the sample application to see this behavior.
Please advise.
Thank you
|
|
|
|
|
Yes, I understood that. I have already downloaded and run your code and already saw the behavior of the "child wpf" when you resize the WPF embedded window.
You are correct that the code I posted will "maximize" the WPF window.
Like I said I think the answer is that you have to do something in WPF to make it work. Hence my posting with a link to the resizing WPF code.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Thank you again Ahmed
I read the article you sent me, and it seems they are trying to intercept the window messages so they can handle the Resizing event and not just the SizeChanged (to catch the message before the size is changed). I was able to do as the sample described, I just cannot find a workaround to fix my problem. I hope anyone can give me a hint.
Thank you for your time
|
|
|
|
|
here some info that might help you
WPF and Win32 Interoperation[^].
It has a section titled "Hosting WPF Content in a Microsoft Win32 Window". MFC is just a "light" wrapper around Win32.
And here's someone's blog about MFC and WPF Interop[^]
I found these by googling for wpf interop[^]
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
For years I've written
const Blah& b = GetMyBlah();
I was taught to read these right to left - ie a reference to a Blah which is const.
A colleague has pointed out that this is in fact incorrect as the const key word is left associative but most compilers allow it (gcc, intel, clang and VC in my case). So it should be written
Blah const& b = GetMyBlah();
When read right to left it's a reference to a const Blah - same thing.
He pointed me to the parashift c++ faq http://www.parashift.com/c++-faq-lite/[^] which was changed recently to put the const between the type and the reference.
Obviously pointers are different as both the pointer and the object pointed to (or both) can be const while a reference is always const.
modified 10-Oct-11 5:18am.
|
|
|
|
|
You're correct, both variants mean exactly the same thing. Whether you write const before or after the type is meaningless and just a matter of style - the latter variant may be a little clearer with respect to the rule of reading types right to left though.
If you wanted to express that your reference is const, then you could place const to the right of the reference operator, like this:
Blah const& b const = GetMyBlah();
However, as Herb Sutter points out (see point 13), this extra const is meaningless since references are always const. Therefore the extra const is usually omitted.
|
|
|
|
|
Good answer Stefan.
So I was trying out some stuff and I was surprised that the VC++ 2010 compiler gave me an error on the second of these saying that void GetBlah2(const Blah*) already has a body.
void GetBlah2(Blah const * blah) { }
void GetBlah2(Blah const * const blah) { }
Yet I am able to declare these variables with the expected meaning:
const Blah* blah1 = new Blah();
Blah const * const blah2 = new Blah();
Is this a bug in the compiler or is such a method (#2 above) disallowed by the C++ standard?
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
In the first function you passed a pointer, not a reference, and you passed that pointer by value. Passing a parameter of type X by value is the same as passing the same parameter as type const X - at least from the point of view of the caller - therefore the declaration of your second function is syntactically the same as the first (again, from the point of view of the caller). The compiler cannot disambiguate any calls to this function into one of the two versions, therefore it does not allow you to overload like that. Follow the link to GOTW I've posted above, IIRC that this was also covered there. In short, if you pass a parameter by value, you cannot overload it only by adding const to that type.
If you meant to pass your pointer by reference, do it this way (using underscore to highlight the change):
void GetBlah2(Blah const *& blah) { } void GetBlah2(Blah const * const blah) { }
This should work.
|
|
|
|
|
I see. Your reply makes sense. It's like trying to declare a const reference (Blah & const). It's redundant.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Not quite. In case of a reference there really is no difference as there is no such thing as a non-const reference. In your example however there would be a difference, but it would only be visible within the code of your function: there, if you defined the parameter const , you could not modify it (locally), whereas if you didn't define it const you could. Of course, since you pass it by value the caller wouldn't notice the difference, basically you gain an additional local variable by not declaring it const .
const Blah* GetBlah1(const Blah*& const b) {
b = 0; return b;
}
const Blah* GetBlah2(const Blah*& b) {
b = 0; return b;
}
const Blah* GetBlah3(const Blah* const b) {
b = 0; return b;
}
const Blah* GetBlah4(const Blah* b) {
b = 0; return b;
}
int main() {
Blah* a = new Blah;
Blah* b = GetBlah4(a); assert(b==0);
assert(a!=0);
delete a;
return 0;
}
|
|
|
|
|
I copied your code into VC++ 2010 and the first two errors do not occur.
Stefan_Lang wrote:
const Blah* GetBlah1(const Blah*& const b) {
b = 0;
return b;
}
const Blah* GetBlah2(const Blah*& b) {
b = 0;
return b;
}
Also, this line gets an error because you can't assign a const value to a non-const value:
Stefan_Lang wrote:
Blah* b = GetBlah4(a);
Anyway, thanks for your help. I understand I think.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Ah, my bad, you are right in all three cases: in the first functions the assignments don't change the reference, only the value they reference. So these examples were not valid for the purpose I wanted to demonstrate. Also, when I tried to compile GetBlah1() I got the warning warning C4227: anachronism used : qualifiers on reference are ignored. This leads me to believe that it is not actually possible to pass a parameter by const reference, and the rightmost const in the signature is ignored, therefore b is not const and may be modified. I wasn't aware of that restriction before.
The function call to GetBlah4() doesn't work because it tries to assign the (const) return value to a non-const variable. Add a const at the start of the line and it should work.
|
|
|
|
|
In the case of pointers, the following 2 lines are the same, where the contents cannot be changed while the pointer can be made to point to another object.
const Blah* p = GetMyBlahPtr();
Blah const* p = GetMyBlahPtr();
Whereas in the following line, the contents can be changed, but the pointer itself cannot be pointed to another object.
Blah* const p = GetMyBlahPtr();
|
|
|
|
|
I can do this in my code
PostMessage(WM_KEYDOWN);
The message gets properly intercepted, no problem.
I need to detect right arrow so I add wParam like this
PostMessage(WM_KEYDOWN,VK_RIGHT,0);
The message is nowhere to be found.
WindowProc does not even detects WM_KEYDOWN.
All this in MFC.
What am I missing?
Thanks for your help.
|
|
|
|
|
You may need to add some detail in your LPARAM variable as described here[^]. Also check the status returned from your PostMessage() call.
|
|
|
|
|
|
I have changed to SendMessage and get expected results.
Also adding GetLastError processing AFTER the PostMessage I get expected results.
Can anybody explain why is this happening?
Especialy when it works when only WM_KEYDOWN is used without the wParam.
The lParam should specify number of repeats of the keyboard, right arrow in my case and should be 0.
I am not using any other language, only US English.
|
|
|
|
|
I just dropped the following code into a program to test the interpretation of "Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user holding down the key."
case WM_KEYDOWN:
sprintf(szText, "repeat count = %d", lParam & 0xFF);
MessageBox(NULL, szText, "Guess What?", MB_OK|MB_ICONQUESTION);
return 1;
While I agree with your interpretation, the message box says that the repeat count is 1.
I'd suppose that when you send WM_KEYDOWN without the wParam, the helper-function that you're calling sets up an appropriate one before calling the 'real' SendMessage, as defined by:
LRESULT SendMessage(
HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
?
|
|
|
|
|
RecordsetPtr rsUrun;
rsUrun.CreateInstance(__uuidof(Recordset));
try{
_variant_t Holder;
CString cQry=_T("");
CString cTmp=_T("");
_stUrun stTmp;
vUrun.clear();
cQry=_T("Select * From urun order by adi");
rsUrun->Open(_variant_t(cQry),AdoTest.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
CStringArray caTmp;
int nPs=0;
while(!rsUrun->adoEOF)
{
stTmp.cUrunAd=_T("");
stTmp.dBirimf=0;
stTmp.nDBID=0;
Holder = rsUrun->GetCollect("urunid"); if(Holder.vt!=VT_NULL) stTmp.nDBID=atoi((char*)_bstr_t(Holder));
Holder = rsUrun->GetCollect("adi"); if(Holder.vt!=VT_NULL) stTmp.cUrunAd=(char*)_bstr_t(Holder);
Holder = rsUrun->GetCollect("birimf"); if(Holder.vt!=VT_NULL) stTmp.dBirimf=atof((char*)_bstr_t(Holder));
vUrun.push_back(stTmp);
CString adi = rsUrun->GetCollect("adi");
listbo1.AddString(_T(adi));
int gfujf = listbo1.GetItemData(listbo1.GetCount()-1);
rsUrun->MoveNext();
SO here is the code, could you please help me on how can I get the listbox item's id in order to use it in an update query?? Here is my button below, I did some work on it but seems no good
void CTestADSSQLDlg::OnBnClickedButton1()
{
_RecordsetPtr rsUrun;
rsUrun.CreateInstance(__uuidof(Recordset));
CString cQry=_T("Update urun set adi='%s' where urunid='%d'", editbo1;
rsUrun->Open(_variant_t(cQry),AdoTest.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
|
|
|
|
|
symeramon wrote: CString cQry=_T("Update urun set adi='%s' where urunid='%d'", editbo1;
Seems a parenthesis has gone AWOL.
symeramon wrote: SO here is the code, could you please help me on how can I get the listbox item's id...
Umm, since you are using MFC, why not just assign it a CListBox member variable? Use ClassWizard (or equivalent).
"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
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|