Home › Forums › TWAIN Classic › Twain Source UI does not respond to my inputs. › Reply To: Twain Source UI does not respond to my inputs.
ok. if you want to keep everything in a dll then you’ll need to throw a window in the dll (I would use a messageOnlyWindow if the platform(s) you’re targeting support it but anything derived from CWnd should work).
You may also need/have to pump the messages yourself because Dlls don’t (typically) pump.
I usually use a whole bunch of classes so that the final consumer doesn’t have to deal with the whole mess.
I’ll give you simplistic example that I’ve used in the past.
the highest level class is simple – doesn’t derive from anything, just a simple class – we ca call it CATwainSession. CATwainSession contains an instance of a class derived from CWinThread, we’ll call it CAMessagePump. CAMessagePump is there because I like having a separate thread do my twain work and because then I don’t have to think about whether I’m trying to run twain from a dialog or a command prompt or a windows service they all behave the same if your class does it’s own pumping. CAMessagePump contains another class derived from CWnd, we’ll call it CAMessegeOnlyWindow. CAMessegeOnlyWindow is there because twain wants to talk to a window.
In CAMessageOnlyWindow you override PreTranslateMessage. PreTranslateMessage is the messageloop that I was talking about… the same one you heard so much about when you read the twain spec – the one that the spec is pretty about when it says you have to modify it to talk to twain…
my PreTranslateMessage method usually ends up looking something like this, ymmv:
BOOL CAMessegeOnlyWindow::PreTranslateMessage(MSG* pMsg)
{
int bProcessed = FALSE;
if (twState >= 5) {
TW_EVENT twEvent;
twEvent.pEvent = (TW_MEMREF)pMsg;
twEvent.TWMessage = MSG_NULL;
TW_UINT16 rc = TWRC_NOTDSEVENT;
rc = CallDSMEntry(&appID, &dsID, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, (TW_MEMREF)&twEvent);
switch (rc)
{
case TWRC_DSEVENT:
bProcessed = TRUE;
break;
case TWRC_FAILURE:
::PostThreadMessage(mpThreadId, UWM_MESSAGE_STOPPUMPING, WPARAM(0), LPARAM(rc));
return FALSE;
break;
}
switch (twEvent.TWMessage)
{
case MSG_NULL:
return TRUE;
break;
case MSG_CLOSEDSREQ:
::PostThreadMessage(mpThreadId, UWM_MESSAGE_SCAN_CANCELLED, WPARAM(0), LPARAM(0));
return FALSE;
break;
case MSG_CLOSEDSOK:
::PostThreadMessage(mpThreadId, UWM_MESSAGE_STOPPUMPING, WPARAM(0), LPARAM(0));
return TRUE;
break;
case MSG_DEVICEEVENT:
return TRUE;
break;
case MSG_XFERREADY:
::PostThreadMessage(dwThreadId, UWM_MESSAGE_STOPPUMPING, WPARAM(0), LPARAM(0));
twState = 6;
TWTransferImage();
return TRUE;
break;
default:
break;
}
}
if (bProcessed)
return bProcessed;
else
return CWnd::PreTranslateMessage(pMsg);
}
For the communication I use registered messages because they’re simple, they’re thread safe, and… huh there was another reason,… maybe two be they’re slipped my mind. Well anyway I use registered window messages but you cold probably use just about anything.
If you have not already read thru Dosadi’s CTwain sample you should probably whip google out right now and search for Dosadi CTwain. there will be a license to read about how you shouldn’t steal and how their code can be used to learn twain but that you can’t sell their code to other people without cutting them in ona pieve of the action – pretty standard stuff, then if that’s all on the up and up you should download and read their code. It explains alot of stuff really well.
.