|
|
Thanks.
<font=arial>Weiye Chen
Life is hard, yet we are made of flesh...
|
|
|
|
|
Hi Chen,
Weiye Chen wrote:
I just need to block/allow certain ip addresse
you can check article, i am sure it will suit your requirement:-
http://www.codeproject.com/internet/smfirewall.asp[^]
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
|
|
|
|
|
Thanks. I'll check that out.
<font=arial>Weiye Chen
Life is hard, yet we are made of flesh...
|
|
|
|
|
Hi all,
I have a trouble with CStringArray class, it is so difficult to me that I'd like to get help from you.
My project has a DLL and a Exe file. In the DLL, threre is a function that used to get a list of strings, I use CStringArray to get the list strings.
For example :
__declspec( dllexport ) void GetCStringArr(CStringArray* pCStringArr)
{
CString cstrText;
for (int i=0; i< 100;i++)
{
cstrText.Format("%d",i);
pCStringArr->SetAtGrow(i,cstrText);
}
}
In the application project, I call GetCStringArr function to get the list string, after calling GetCStringArr function, I have the needed list string and can access all strings in the list(CStringArray),everthing is OK but when I release the CStringArray object, my project has a exception :
// m_ArrText is a CStringArray object, it is a member variant of //CTestCstringArrDlg class
void CTestCstringArrDlg::OnGetButton()
{
GetCStringArr(&m_ArrText);
for (int i=0;i<10;i++)
{
MessageBox(m_ArrText.GetAt(i));
}
CTestCstringArrDlg.RemoveAll(); // This line code has exception
}
If I declare, use and release CStringArray variant in only application or only in Dll, everything is OK. I don't known why when I declare CStringArray in App but add it's item string in Dll, I can get all Item string in CStringArray but when I release CStringArray I alway have problem.
Please help me to solve the problem!
|
|
|
|
|
Objects allocated within the DLL should only be released by the DLL. Expose a new method in your DLL that frees up a CStringArray and call that on m_ArrText .
/ravi
My new year's resolution: 2048 x 1536
Home | Music | Articles | Freeware | Trips
ravib(at)ravib(dot)com
|
|
|
|
|
Thanks for your help, I have tried to do as your comment, it is useful for me and is my need.
Thank you very much.
|
|
|
|
|
It might be because of the EXE and DLL being built with different options or defines...
Does sizeof(CString) give the same result in both the EXE and DLL?
--
jlr
http://jlamas.blogspot.com/[^]
|
|
|
|
|
Make sure the DLL is an MFC extension DLL and that the App uses MFC as a shared DLL. This way you will be able to allocate/release memory and objects wherever you want.
|
|
|
|
|
Hello gurus,
I have a C question this time. An easy one
I wish to write a function that modifies a 2D array of unsigned char .
My array looks like this:
unsigned char map[0x40][0x20];
I call an update function:
UpdateMap(map, nLevel);
and the map should be modified. But I have forgotten hwo to write the header of the UpdateMap function. Can some one remind me please?
its code is simply like that:
<br />
void UpdateMap([I have forgotten how to write the header])<br />
{<br />
int i=0, j=0;<br />
for (i=0; i<0x20; i++)<br />
for (j=0; j<0x20; j++)<br />
map[i][j]=map[i+0x20][j]=g_levelMaps[i+(nLevel*0x20)][j];<br />
}<br />
<br />
Thanks for the help.
Best regards.
Fred.
There is no spoon.
|
|
|
|
|
It's an unsigned char **.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Hi Christian,
That's what I have done, but I have a warning:
"Parsing argument 1 of 'UpdateMap' from incompatible pointer type"
That's why I have posted a new thread
I have declared my array as an unsigned char and also in the header of the function.
fred
There is no spoon.
|
|
|
|
|
I think that when I did it, I declared an unsigned char ** and then called new on it to build the array. But that's what it is, you can't pass an array as such AFAIK.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
ok, my array is not initialized by the new operator. It is decalred like a standard array:
unsigned char map[0x40][0x20]
fred
There is no spoon.
|
|
|
|
|
You can code it as follows:
void UpdateMap(unsigned char map[0x40][0x20])
{
int i=0, j=0;
for (i=0; i<0x20; i++)
for (j=0; j<0x20; j++)
map[i][j]=map[i+0x20][j]=g_levelMaps[i+(nLevel*0x20)][j];
}
void test()
{
unsigned char map[0x40][0x20];
UpdateMap(map);
}
Hope that helps,
--
jlr
http://jlamas.blogspot.com/[^]
|
|
|
|
|
It works if you specify the array bounds ? Cool.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Christian Graus wrote:
It works if you specify the array bounds ? Cool.
It does work
For an array of n dimensions you need to specify at least (n-1) bounds, because otherwise the compiler has no way to calc the offset for a given element. For example, if you have int matrix[3][5] (3 rows, 5 columns), then the element at matrix[i][j] (row i, column j), can be computed as *(matrix+(i*5)+j) , that is, increment the matrix pointer so as to skip i rows of 5 elements each, then skip j elements, and then dereference the resulting pointer.
As can be seen in the example above, the number of rows isn't strictly needed, though (just like the number of elements isn't actually needed for an array of only one dimension). In fact one could even write a function that received as its argument a matrix of unbounded rows and n columns.
void test(int matrix[][5])
{
matrix[2][3] = 1;
}
void main()
{
int matrix[3][5];
test(matrix);
}
If on the other hand the test function received the matrix as an int** , there'd be no way to know how many elements to skip for each row. The test function would compile, but the main function not, because int[3][5] is not the same as int** , the latter being a pointer to a pointer to an int [1]. In fact if we changed the test function to
void test(int** matrix)
{
matrix[2][3] = 1;
}
The expression matrix[2][3] would compile to something entirely different than before. With matrix defined as int** an expression matrix[i][j] would translate to *((*(map+i))+j) , that is in the example, incrementing the matrix pointer by 2, dereferencing the result, using that value as a pointer, incrementing it by 3 and then dereferencing that! To keep that working as before, we'd need to also alter the main function as follows:
void main()
{
int matrix[3][5];
int* rows[3];
for (int i = 0; i < 3; i++)
rows[i] = &matrix[i][0];
test(rows);
}
There's still one additional correct way of writing the code, which can be used if one doesn't want test to be restricted to a particular number of columns:
void test(int* matrix, int nCols)
{
matrix[2*nCols+3] = 1;
}
void main()
{
int matrix[3][5];
test(matrix[0],5);
}
[1] Depending on how it's used, it can also be seen as a pointer to an array of pointers to int s, or as a pointer to a pointer to an array of int s, or as a pointer to an array of pointers to arrays of int s.
--
jlr
http://jlamas.blogspot.com/[^]
|
|
|
|
|
Hi,
Thanks for the trick
As my array will be modified by other functions, I simply put the array in global and the functions modify it and it works that way
Thanks.
Fred
There is no spoon.
|
|
|
|
|
u can mention the first argument in the header as unsigned char(*map)[0x20]
(pointer to an array of size 0x20)
|
|
|
|
|
Do not use global variables unless you have no other choice. See my response to a similar question here.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
I have an EDIT box and I'd like to silently trap and eat certain characters.
I can catch WM_CHAR, check for the key, and return 0.
I guess I'm asking if this is the right thing to do?
I'd prefer to catch WM_KEYDOWN, and somehow return something that says "don't bother translating this key. Do not translate. Do not send out WM_CHAR ..."
But to no avail.
------
Here is another example. I want to convert every character typed to +2. So, if the user enters "abc" I want to print "cde" to the window. "ejv" == "glx". Following the above approach, if I capture and eat the "a" character in WM_CHAR, and then resend "c" ... naively, I'd capture the "c" and cancel it ... and send "e" ... etc etc. and I've got a crazy endless loop.
Some languages have event handlers that include the character code by reference -- and if you change the character code - whatever you changed it to is what is passed to the underlying window. Is there a low level facility to do that in win32? Can I capture WM_KEYDOWN and change the key so that WM_CHAR is correct.
Or, do I just need to manage some tricky key issues (if user didn't send this key, process it, else, cancel it and resend the new key).
Should I bother with with the TranslateMessage function? I'm just sure this is a common enough idiom that someone else has asked this and has an elegant solution ... any pointers would be great!
----
One more example - I'm implementing vi or emacs ... and I've got a slew of keyboard commands. There are just times when converting keys to WM_CHAR is a waste of CPU. If I'm in vi's navigation mode - I really don't need to send any characters to the window. I guess I can keep canceling them in WM_CHAR -- but it seems there should be a more elegant way to do so ...
I'm not a big fan of global hooks - but maybe they are warranted in this case?
Thanks in advance for any suggestions,
-Luther
|
|
|
|
|
You didn't say if you are using MFC or not. If you are using MFC (and possibly WTL ) you can do this quite easily by overriding your CEdit derived class's PreTranslateMessage function and handling the WM_KEYDOWN message there.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
"Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04
"There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05
Within you lies the power for good - Use it!
|
|
|
|
|
Ahh ... nice suggestion!
I am not using WTL per se, but my own OO framework. I mimic several parts of the WTL including THUNKING the wndproc - but I've not worried about the PreTranslateMessage mechanism ... till now.
So, conceptually, I don't want to translate WM_KEYDOWN to the WM_CHAR if it is a tab character ... I will read up - but I am guessing that PreTranslateMessage leads to TranslateMessage unless you return 0 or something like that ...
I wonder if I can also change the keydown here as well ...
At any rate, I think your point is ... I need to intercept the message before calling TranslateMessage - and the WTL lib provides an easy way to do this on a per HWND basis. Seems like alot of overhead ... does the MFC or WTL message loop call PreTranslateMessage for EVERY window class object?
Thanks,
-Luther
|
|
|
|
|
This is EXACTLY what I was looking for
Thanks PJ!
BOOL DialogName::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_RETURN || pMsg->wParam==VK_ESCAPE)
pMsg->wParam=NULL ;
}
return CDialog::PreTranslateMessage(pMsg);
}
|
|
|
|
|
I have a Class called CDriver which is as follows:
class CDriver {
public:
// Constructor
CDriver();
CDriver(CDriver &driver); // Copy constructor
CDriver operator =(const CDriver d);// Assign one to another
~CDriver();
// Varables
CString csFirstName;
CString csMI;
CString csLastName;
CString csBirthDate;
CString csASSN;
CString csStreetAddr;
CString csCity;
CString csState;
CString csZip;
CString csHomePhoneNum;
CString csHireDate;
CString csTruckAssigned;
};
Now I made a vector: "vector<<cdriver>> vecDriver"; Also a CString vector: "vector<<cstring>> myCStringvec"; and an iterator "vector<<cstring>>::iterator myIT";
None of these work properly! I can get the "myCStringvec.push_back(temCString)"; to accept one and only one CString. I NULLed temCString before reloading it with data then again used: "myCStringvec.push_back(temCString)"; to no avail. WHY?
vecDriver doesn't work at all nor does myIT. Please ignore the "<< and >>" it would not show what I wanted to show without using two each!
C++ is my favorite programming language
|
|
|
|