|
shizhanbiao wrote: How to do it. How to do what, exactly? Create a dialog box with two buttons? Implement drag and drop? Swap two buttons? Be specific with what you are asking. It's Wednesday so the mind-reading pills are wearing off.
"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
|
|
|
|
|
Hi all, I read some more on MSDN and found out that if you call a stored proc ( SQL Server in my case ) which returns a record set and also populates an *output* parameter , the parameters return value is in a separate record set. What I did was print all my records then move to the next set with:
spRst = spRst->NextRecordset();
bstr_t NumRecs = ((bstr_t)pCmd->Parameters->Item["Count"]->Value)->GetBSTR();
A lesson learnt.
Hi all, the code below works fine except for the retrieval of the @Count parameter which is of type *output* it always returns zero - any ideas ? ( it's this line of code : _tprintf(_T("Records found = %d\n\n"),spCmd->Parameters["@Count"]);
Many thanks
#pragma region Includes and Imports
#include "stdafx.h"
#include <atlstr.h>
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" rename("EOF","EndOfFile")
using namespace ADODB;
#pragma endregion
static ADODB::_ParameterPtr CreateParam(_bstr_t Name, _bstr_t Value, int Size, ADODB::DataTypeEnum Type, ADODB::ParameterDirectionEnum Direction);
static ADODB::_ParameterPtr CreateParam(_bstr_t Name, int Value, int Size, ADODB::DataTypeEnum Type, ADODB::ParameterDirectionEnum Direction);
int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 4)
{
_tprintf(_T("Usage: CppUseADO.exe \"Search for this\" Y|N to specify combined or not Y|N to include address search\n"));
return -1;
}
int i = 0;
::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
ADODB::_ConnectionPtr spConn = NULL;
ADODB::_RecordsetPtr spRst = NULL;
ADODB::_CommandPtr spCmd = NULL;
ADODB::_ParameterPtr spParam = NULL;
_bstr_t bstrSearchExp(argv[1]);
_bstr_t bstrCombined(argv[2]);
_bstr_t bstrSearchAddress(argv[3]);
_bstr_t bstrConn("dsn=CMS;");
try
{
spConn.CreateInstance(__uuidof(ADODB::Connection));
_tprintf(_T("Connecting to the database ...\n"));
spConn->Open(bstrConn, "", "", NULL);
spCmd.CreateInstance(__uuidof(ADODB::Command));
spCmd->ActiveConnection = spConn;
spCmd->CommandText = "SearchOnCreditorName";
spCmd->CommandType = ADODB::adCmdStoredProc;
spRst.CreateInstance(__uuidof(ADODB::Recordset));
spParam = CreateParam("@PartWord", bstrSearchExp, 35, ADODB::adVarChar, ADODB::ParameterDirectionEnum::adParamInput);
spCmd->Parameters->Append(spParam);
spParam = CreateParam("@Combined", bstrCombined, 1, ADODB::adChar, ADODB::ParameterDirectionEnum::adParamInput);
spCmd->Parameters->Append(spParam);
spParam = CreateParam("@SearchAddress", bstrSearchAddress, 1, ADODB::adChar, ADODB::ParameterDirectionEnum::adParamInput);
spCmd->Parameters->Append(spParam);
spParam = CreateParam("@Count", 0, 8, ADODB::adInteger, ADODB::ParameterDirectionEnum::adParamReturnValue);
spCmd->Parameters->Append(spParam);
_tprintf(_T("Searching the CMS Database for value %s \n"), (PCTSTR)bstrSearchExp);
spCmd->Prepared = true;
spRst = spCmd->Execute(NULL, NULL, NULL);
_tprintf(_T("Records found = %d\n\n"),spCmd->Parameters["@Count"]);
while (!spRst->EndOfFile)
{
variant_t vtClaimRef(spRst->Fields->Item["ClaimRef"]->Value);
variant_t vtCreditorName(spRst->Fields->Item["CreditorName"]->Value);
variant_t vtAddr1(spRst->Fields->Item["AddrLine1"]->Value);
variant_t vtAddr2(spRst->Fields->Item["AddrLine2"]->Value);
variant_t vtAddr3(spRst->Fields->Item["AddrLine3"]->Value);
_tprintf(_T("%s\t %s\t %s %s %s\n"),
vtClaimRef.vt == VT_NULL ? _T("(DBNull)") : (PCTSTR)vtClaimRef.bstrVal,
vtCreditorName.vt == VT_NULL ? _T("(DBNull)") : (PCTSTR)vtCreditorName.bstrVal,
vtAddr1.vt == VT_NULL ? _T("(DBNull)") : (PCTSTR)vtAddr1.bstrVal,
vtAddr2.vt == VT_NULL ? _T("(DBNull)") : (PCTSTR)vtAddr2.bstrVal,
vtAddr3.vt == VT_NULL ? _T("(DBNull)") : (PCTSTR)vtAddr3.bstrVal);
i++;
spRst->MoveNext(); // Move to the next record
}
_tprintf(_T("%d records printed for %s\n"), i, (PCTSTR)bstrSearchExp);
}
catch (_com_error err)
{
_tprintf(_T("\nOops something went wrong ! probably no records found\n"));
_tprintf(err.Description());
_tprintf(err.ErrorMessage());
_tprintf(_T("\n\n"));
}
/////////////////////////////////////////////////////////////////////////
// Clean up objects before exit.
//
_tprintf(_T("Closing the connection...\n"));
// Close the record set if it is open
if (spRst && spRst->State == ADODB::adStateOpen)
spRst->Close();
// Close the connection to the database if it is open
if (spConn && spConn->State == ADODB::adStateOpen)
spConn->Close();
::CoUninitialize();
return 0;
}
static ADODB::_ParameterPtr CreateParam(_bstr_t Name, _bstr_t Value, int Size, ADODB::DataTypeEnum Type, ADODB::ParameterDirectionEnum Direction)
{
ADODB::_ParameterPtr spParam;
spParam.CreateInstance(__uuidof(ADODB::Parameter));
spParam->Direction = Direction;
spParam->Name = Name;
spParam->Type = Type;
spParam->Size = Size;
spParam->Value = Value;
return spParam;
}
static ADODB::_ParameterPtr CreateParam(_bstr_t Name, int Value, int Size, ADODB::DataTypeEnum Type, ADODB::ParameterDirectionEnum Direction)
{
ADODB::_ParameterPtr spParam;
spParam.CreateInstance(__uuidof(ADODB::Parameter));
spParam->Direction = Direction;
spParam->Name = Name;
spParam->Type = Type;
spParam->Size = Size;
spParam->Value = Value;
return spParam;
}
We can’t stop here, this is bat country - Hunter S Thompson RIP
modified 6-Nov-13 2:40am.
|
|
|
|
|
I cannot find a reference for the CreateParam function anywhere so it's difficult to check your settings. Also, it would help if you put <pre> tags around your code.
Veni, vidi, abiit domum
|
|
|
|
|
OK, sorry Richard ' the CreateParam function is a UDF , I included it in the code sample - also I didn't know about the
tag
<div class="signature">We can’t stop here, this is bat country - Hunter S Thompson RIP</div>
|
|
|
|
|
pkfox wrote: also I didn't know about the
tag
Select the text, and click either the "code" or "var" link above the message box. I would add to this that most of the code you've shown is not relevant to the problem. Only include what is absolutely necessary so that more folks will read your post.
"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
|
|
|
|
|
Not the 'var' link for lines of code.
Veni, vidi, abiit domum
|
|
|
|
|
pkfox wrote: the CreateParam function is a UDF And which of these[^] is that referring to?
Veni, vidi, abiit domum
|
|
|
|
|
User defined function.
We can’t stop here, this is bat country - Hunter S Thompson RIP
|
|
|
|
|
These terse comebacks are really not a lot of use. If you want some help with this issue then you need to provide some useful details.
Veni, vidi, abiit domum
|
|
|
|
|
You asked what I meant by UDF so I told you - I've marked the question as solved so it is effectively closed.
We can’t stop here, this is bat country - Hunter S Thompson RIP
|
|
|
|
|
Hello. I have been able to capture audio stream using WASAPI using this sample on MSDN.
But the problem is that the sample can capture only for specified time defined as hnsBufferDuration in IAudioClient::Initialize(). After that time has elapsed, it stops capturing. How can I tweak this sample to continue capturing until I click on a button or something like that? (Perhaps using two buffers ? but I don't know how to use them).
One more thing: when this sample runs, GUI does not respond to my click events.
Thanks for any pointers.
This world is going to explode due to international politics, SOON.
|
|
|
|
|
The sample does not stop capturing by itself. Capturing in the sample code is stopped when the pMySink->CopyData() functions sets the bDone boolean variable. It is up to you to implement this function to handle the incoming data and set the stop flag conditionally.
Your GUI does not respond anymore because its message loop is never called while the capturing loop is executed. To avoid this, create a worker thread and perform the capturing inside that thread. Using worker threads is an advance topic. So you should read about them first (e.g. the Using Worker Threads[^] CP article).
|
|
|
|
|
Working on a Win32 C++ (non-MFC) application and I've run into an issue that I can work around but from reading the MSDN documentation I shouldn't have to do this. I'm under the impression that a child window
for example:
CreateWindowEx(WS_EX_CHIENTEDGE,
TEXT("LISTBOX"),
TEXT("DEVICES"),
WS_CHILD | WS_VISIBLE | ...
10,10
mainWindowHandle,
(HMENU)IDC_DEVICELISTBOX,
mainWindowInstance, NULL)
should pass all messages to its parent message queue and should be processed in its parent's WndProc callback message? This does not function like this in my application so I have to use "GetWindowLong" and "SetWindowLong" to define a callback message for each control child window.
I've seen a lot of examples but I'm still not clear if my application is working as expected or if I'm just stressing out over nothing. Thanks for any help in advance.
modified 3-Nov-13 14:21pm.
|
|
|
|
|
|
A bit of correction: Each thread has a message queue and each window belongs to the thread that created it. When you send a message to a window then the message is (automatically) put into the message queue of the thread that owns the window. The message will be passed to the window by the owner thread when it decides to get a message from its message queue and decides to dispatch it (EDIT: a bit of correction here: sent messages and some other messages are handled specially (like WM_QUIT/WM_PAINT) and/or out of order of the queue). A child control sends most of its commands/notifications (not window messages!!!) to its parent window and these are automatically put into the owner thread of the parent window (the child window has nothing to do with the owner thread of the parent window and the message queue of the owner thread, that is handled by the system automatically). Only a few specific "messages" (commands/notifications) are passed to the parent window, the rest (most) of the messages are processed by the window proc that belongs the the class of the child control. The "notifications" and "commands" that are passed to the parent usually arrive as WM_COMMAND and WM_NOTIFY messages to the window proc of the parent window. (There are a few exceptions, like WM_CTLCOLOR...)
modified 3-Nov-13 13:06pm.
|
|
|
|
|
Not confusing at all! I think things are getting clearer. This is my main initial confusion.
Window Procedure
A window procedure is a function that receives and processes all messages sent to the window. Every window class has a window procedure, and every window created with that class uses that same window procedure to respond to messages.
The system sends a message to a window procedure by passing the message data as arguments to the procedure. The window procedure then performs an appropriate action for the message; it checks the message identifier and, while processing the message, uses the information specified by the message parameters.
I think the key confusion for me is what Windows considered a "CLASS".
pasztorpisti, thanks again but can you clarify something for me? When you say "(not window messages!!!)" your not talking about "WM_*" messages but messages that are specific to a class like "BM_*", "LB_*", "CB_*", and ...?
|
|
|
|
|
You are right. Classic window messages (like WM_PAINT, WM_SIZE, ...) are all processed by the window proc of the control itself (that is window class specific). Specialized child windows (controls like Button, Edit, ...) are designed that they send only a few messages to the parent window (like WM_COMMAND message when the user presses a button, and WM_NOTIFY with control specific struct pointer).
I guess this design was created because back in the old days people wrote their programs in procedural languages (C, Pascal) and in that case it is more comfortable to write just one windowproc for your window and to handle all child control messages there instead of writing a lot of window procs for all buttons, edit boxes, and so on... If you think about it, most of the core windows API is also a C interface.
The irony here is that today GUIs are mostly built with object oriented GUI frameworks where one control is one object (I'm not talking about MFC here, that is at most 1/3 object oriented, Qt is a much better example). Such a framework needs to have/handle all control specific messages/notifications in the object associated with the control. For this reason the window specific implementation of such a framework usually delegates the handling of child control speicific messages from the parent object to the child object. Later the programmer usually registers an event handler into the object of the child control. You also need all control specific messages in the object associated with the child control when you want to write reusable specializations of some windows-builtin child controls (like static or edit).
|
|
|
|
|
Hi friends,
I tried out something like this which is given below in VC++ by referring Dennis M. Ritchie (ANSI C second edition) book examples.
struct Key *low = &tab[0];
struct Key *high = &tab[n];
struct Key *mid;
mid = low + (high-low) / 2; // Error: cannot convert from 'int' to 'struct Key *'
My question is how they are using this expression mid = low + (high-low) / 2;?. I don't know whether I misunderstood the concept or there is some difference between ANSI C and VC++. Please anyone help me in this.
Regards,
S.Shanmuga Raja
|
|
|
|
|
Which compiler gives the error? I just tried this with Visual Studio 2010 C++ compiler and it compiles correctly, as it should, in both .c and .cpp versions.
Veni, vidi, abiit domum
|
|
|
|
|
There is a difference between ANSI C, some other C++ compilers, and what Visual Studio allows for pointer arithmetic.
Pointer arithmetic is not allowed on all platforms, as least not allowed the way you have it. There is a ptrdiff _t macro that allows taking pointer differences on many platforms, but I'm not sure whether that is allowed in ANSI C or not. In any event, that is not what you need.
Some compilers will let you cast a pointer to be type size_t, however, that is not portable across all platforms and compilers and is generally not a good practice.
Presumably, the array tab is defined to be an array of Key structures:
So, to write portable code, write code something like this:
int BinarySearch(int low, int high, struct Key x)
{
int index = -1;
int mid = 0;
while (low <= high)
{
mid = (low + high) >> 1;
if (firstKeyLessThanSecondKey(x, tab[mid]))
{
high = mid - 1;
}
else if (firstKeyLessThanSecondKey(tab[mid], x))
{
low = mid + 1;
}
else
{
index = mid;
}
}
return index;
}
To search the entire tab array for a Key equal to x , pass 0 for low and the array length minus 1 for high .
This will return -1 if the Key that matches x is not found, otherwise the index into the array tab for the key that matches x will be returned.
Because the values of low and high are always positive, a shift can be used for the divide by 2.
mid = (low + high) >> 1;
Of course, you'll have to modify this code for your application. I made some assumptions based on the book you cited.
Also, if the Key structure isn't very small, then instead of passing the Key structure by value, you might want to pass a pointer to a Key to both the BinarySearch function and to the FirstKeyLessThanSecondKey function.
Finally, I didn't compile and test this. I'm never 100% sure if code is correct until I debug it under varied conditions. If not correct, I expect this is very close to correct.
modified 2-Nov-13 0:51am.
|
|
|
|
|
The MSDN says if you you return TRUE from LVN_EndLabelEdit notification, the control will accept the new edited text.
It's not true for my experiments.
I tried return TRUE, it didn't work, the label stays unchanged.
...
BOOL OnEndLabelEidt( ..., LPNMLVDISPINFO pDispInfo)
{
return TRUE ; // doesn't work
// so I have to do it manually
LVITEM item ;
...
item.pszText = pDisInfo->item.pszText ;
ListView_SetItem(hListview, &item ) ; // then it works
}
As it isn't TRUE for any other notfications.
such as TreeView::TVN_EndEditLabel.
TreeView::TVN_EXPANDING returns TRUE expands the node anyway, which conflicts with the Documentation either.
Could someone give me a clue? Thanks.
|
|
|
|
|
If you think the documentation is wrong then you should report it to Microsoft.
Veni, vidi, abiit domum
|
|
|
|
|
I am confused. I think there must be something wrong in my comprehension,
|
|
|
|
|
|
<pre lang="cs">void Test::OnDrawSortArrow(CDC* pDC, CRect rectArrow)
{
Metafile * emf = NULL;
emf = LoadMetafile(IDR_ICON_EXPAND, NULL, true);
Gdiplus::Bitmap* image = BitmapFromEmf(emf, 8, 8, Color(255,82,82,82), 0);
HICON hIcon = NULL;
if(IsAscending())
image->RotateFlip(Rotate180FlipNone);
image->GetHICON(&hIcon);
pDC->DrawIcon(rectArrow.TopLeft().x - 20, rectArrow.TopLeft().y - 10, hIcon);
delete emf;
}</pre>
|
|
|
|
|