Telephone app manages a TV telephone poll.
Features
→ To set many line sockets to a single answer. (Like if there are only two answers and 8 lines, we set first 4 lines for the first answer, and the rest lines for the second answer.)
→ Each telephone line socket can have its own sound answer. (For example, if the vote is country president election: first line answers «Thank you for voting for mr.Bush», second line answers «Thank you for voting for mr.Obama» and so on.)
→ Presents results both as xml and tga image files
→ Capable to gather calls from actual hardware accepting device and over internet (from FTP or HTTP server of a telephone poll service company)
→ Multiple image outcome
→ Save/ Load/ Erase statistics (file) – to conduct the same poll more than once a day with a break in between (For example, if you need those telephone lines in the midday for other purposes, you may stop the poll, save current statistics to a file, quit the app, and then at evening launch the app back up, load stored statistics from a file and continue the poll.)
Resources I've used
→ Liner-8 telephone modem API
→ TGA graphics file editor object (COM)
→ MS CInternetFile
→ MS MFC
Links
→Video from presentation
→Presentation (PPT file, 2.2Mb)
→Telephone Voting Statistics
→Example of project file
→Sketches & plots
[Issue] Save/Load calls statistics (*.SLPhoneStat xml file)
[Owner] Consumer
[Status] +
[Description] They want to conduct a poll twice a day with
a break in between. So I gotta store all the necessary data
to restore the poll later:
++ latest line factors (CSettingsParser::m_secLines[].dCoef);
++ true line income calls (CPhoneLine::m_nCalls);
++ aggregated multiplied variant calls (m_Cache_dVariant_MultipliedCalls[]);
++ manual variant calls (m_Cache_dVariant_ManualCalls[]);
[Q] What's the procedure now in resetting calls after
hitting “Stop” button?
Because now I may wanna save data into statistics
file and may not want to. And when I start new poll,
I also should have a choice – either to start with
data from previous time (or loaded from xml) or to start
from scratch.
Seems like there should be a separate button which
resets current statistics. Which finally makes it 3
buttons: Save/ Load/ Erase.
[ToDo] + Add 3 bitmap buttons for Save&Load&Erase facilities.
++ add the owner-draw bmp buttons onto GUI;
++ paint/find bitmaps;
++ declare user defined messages;
++ catch 'em; // 1
++ move buttons on resize (each of these 3 buttons must have equal hor coords as -1, ++, -- buttons); //1
++ add tooltips for each of Save&Load&Erase buttons; //1
++ setup unreenterable handle procedures; //1
++ add corresponding items into tray menu; //1
++ disable in active mode; //1
++ disable menu items in active mode. //1
[ToDo] + XML (.SLPhoneStat):
++ figure out connection mechanism;
++ declare TAGs and ATTRs;
++ write save proc;
++ write load proc; //2
++ connect stat file data with the //2
+++ Fix: Factor edits change CSettingsParser factors IN ANY mode (now only if active mode); //2
+++ CSettingsParser (factors); //2
+++ CPhoneStation object (aggregated values); //2
+++ CPhoneLine objects (true calls); //2
+++ LineCalls edits,
LineFactor edits,
LineFactor spins,
Variant StatusBars
– all through CPHELDlg::UpdateControls(); //2
[ToDo] + Fetcher Save/Load/Erase; //2
[Q] How do I deal with line factors? Do I assign new line factor values
to the CSettingsParser members right on click? Or I dump those factors into
CSettingsParser only on Save()? //2
[Solution] + I must parse settings file only (a) OnInitDialog() and
(b) OnPopupSettingsFile(). I MUST NOT parse it OnStart(), otherwise
it'll override line factors. //2
[ToDo] + Make LineCallsEdit able to gather data both from hardware telephone
line AND from network fetched calls. //2
[Issue] Multiple statistics image files
[Owner] Consumer
[Status] +
[Description]
Consumer wants to have multiple statistics
image files to use 'em in different mediae: regular CRT TV,
plasma screen, etc.
[Question]
(Graphical objects inside RGN file)
Should I keep checking all the specified in project file
BARs and TEXT fields in all the specified region files?
(Previously it was the only region file).
[Solution]
(A){v} Run through all the RGN files and ONLY NOTIFY user if some
file doesn't contain specified object. Message goes like this:
«RGN file X doesn't contain the following object(s): Answer1, AllCount, BarOne.
RGN file Y doesn't contain the following object(s): Answer7, AllCount, BarTwo.»
(B) Do (A), but instead of notification make a fatal error.
(C) Don't check at all.
(D) Change project file format:
(D.1) Create group RgnX (where X is number).
(D.2) Move {BarSize, Bar4All, Output, Region} settings from
General group into RgnX group.
(D.3) Make Bar & Text groups unambiguously connected
with only RgnX group by putting the same index at the end of group names: BarX, TextX.
In (D) case I'll have means to verify everything 100%, but
I'll have to CHANGE project file format and so all the current
consumers will have to spend several days figuring out what the
hell is wrong.
I see contradictory requests: flexibility versus foolproof.
Flexibility means to allow user to do whatever one wants and give
more freedom. Foolproof means to follow certain strict rules and
no step aside. So, the best way is probably to notify but don't
make a big deal of graphical object absence in a RGN file.
[ToDo] +
(RGN-TGA data structure).
Create new data structure consisting of two CString variables:
m_strRGN,
m_strTGA.
Add CAtlArray
Now there is going to be several pairs {RGN-file[i], TGA-file[i]}
instead of a single one. And so I gotta make sure that:
(1) ++ For every RegionX setting there is OutputX setting available.
(2) ++ Every RegionX file MUST exist.
(3) ++ ... and be loadable: if feeded fake region into Fert's COM,
then it blows up the app next time (even if create new instance after
the incident).
(4) ++ TGA file must have correct name: [A-a0-9]+.tga
(5) ++ For every RGN file enumerate all the missing graphical objects
and text fields from project file. And notify user, BUT never deny
from starting the poll. Make user responsible for composing RGNs and
keep it in accordance with the project file.
+++ Implement verify_region_objects() procedure as a member of CSettingsParser.
+++ Design a simple dialog form with ICONEXCLAMATION icon, edit control
and OK button, saying: Region file "X.rgn" doesn't contain the following object(s):
* BarOne
* BarTwo
* CountAll
* Answer3
Region file "Y.rgn" doesn't contain the following object(s):
...
[ToDo] +
(Composing TGA images).
When the composing time comes up, I get a list of pairs:
{RGN-file, TGA-file}
and for each of them I conduct already approved TGA-composing procedure
only including the following checks:
(1) ++ make sure current TEXT FIELD exists in current RGN file;
(2) ++ BAR.
++ I also feel a performance bottleneck in TGA composing and there
are simple actions to improve efficiency:
+++ stop checking textboxes and bars each composing time. Instead,
make up 2 arrays for each {RGN, TGA} pair with available object INDECES
from settings.
+++ stop loading region file each composing time. Instead, add a
IDDSRegionObj member field into RGNTGAPair structure, create instance
and load region file ONCE on verification step. Then use already opened
object to compose TGA.
+++ stop allocating memory each time. Instead, do it once on load
region file.
[Issue] Total calls, manual calls onto GUI
[Owner] Consumer
[Status] +
[Description] Consumer requests to put total amount of
all the calls (including fake ones),
then fake manual calls,
and finally percent of manual fake calls.
[ToDo] + Figure out class member functions to get total calls
and manual calls.
m_Cache_dAllCalls
m_Cache_dVariant_ManualCalls
m_Cache_dVariant_MultipliedCalls
m_Cache_dPercents: (mult_calls + manual_calls)/all_calls
[ToDo] + Workout a question where to put those numbers on the
GUI.
[ToDo] + Write CTotalCallsStatic and make it work.
[ToDo] + Write CManualCallsStatic and make it work.
++ Statistics data: absolute mode.
++ Resizing: just move right side exactly equal to width $delta.
Ask CDialogLayout to provide width delta, and move static field
horizontally just equal to calculated value.
[ToDo] + Put manual calls number into bar.
Ivan Yurlagin,