The Winamp Remote Control suite
a remote control client and plugin for Winamp 2.x, 5.x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
remoteDM.cpp
Go to the documentation of this file.
1 #include <vcl.h>
2 #pragma hdrstop
3 
4 #include "remoteDM.h"
5 
6 #include "WinampClientBase.h"
7 #include "DetailsF.h"
8 #include "CursorGuard.h"
9 #include "CommandF.h"
10 #include "SettingsF.h"
11 #include "ServersF.h"
12 #include "RPCException.h"
13 #include "remotestrs.h"
14 #include "AboutF.h"
15 #include "rpcbind.h"
16 
17 #pragma package(smart_init)
18 #pragma resource "*.dfm"
20 
21 __fastcall TdmRemote::TdmRemote(TComponent* Owner)
22  : TDataModule(Owner)
23 {
24 }
25 
26 void TdmRemote::hookEvents(TForm * NewForm, TForm * PriorForm)
27 {
28  // hook the generic form events so the state can be managed
29  // drag and dock is currently disabled
30  NewForm->OnStartDock = ChildFormStartDock;
31  // close event
32  NewForm->OnClose = ChildFormClose;
33  {
34  if (PriorForm)
35  PriorForm->OnStartDock = NULL;
36  if (PriorForm)
37  PriorForm->OnClose = NULL;
38  }
39 }
40 
41 void __fastcall TdmRemote::ChildFormStartDock(TObject *Sender, TDragDockObject *&DragObject)
42 {
43  frmMain->StartDock(Sender, DragObject);
44 }
45 
46 void __fastcall TdmRemote::ChildFormClose(TObject * aForm, TCloseAction & aAction)
47 {
48  // handle the update
49  if (aForm == FPlaylistForm)
50  {
51  this->ViewPlaylist->Checked = false;
52  }
53  if (aForm == FMainForm)
54  {
55  this->ShowMainForm->Checked = false;
56  }
57  if (aForm == FSettingsForm)
58  {
59  this->ViewVolume->Checked = false;
60  }
61  if (aForm == FCommandsForm)
62  {
63  this->ViewToolBar->Checked = false;
64  }
65 
66 }
67 
68 void __fastcall TdmRemote::GetFilenames(int Start, int Stop, TStringList * Files)
69 {
70 
71 int i;
72 
73  for (i = Start ; i < Stop; i++)
74  {
75  Files->Add(dmRemote->client->getPlayListItem(i, false).c_str());
76  } // for
77 
78 }
79 
80 void __fastcall TdmRemote::DoAddFiles(TStrings * Files, int selectedIndex)
81 {
83  string filelist = Files->Text.c_str();
84  vector <string> playlist;
85  for (int i = 0 ; i < Files->Count ; i++)
86  playlist.push_back(Files->Strings[i].c_str());
87  client->setPlayList(playlist);
88  if (selectedIndex >= 0)
89  client->setPlaylistIndex(selectedIndex);
90 
91 }
92 
93 void __fastcall TdmRemote::DropFiles(TStringList * DropFiles, int DropIndex)
94 {
95  std::auto_ptr<TStringList> Playlist(new TStringList());
96 
97  // get the top of the list
98  if (DropIndex > -1)
99  GetFilenames(0, DropIndex, Playlist.get());
100  else
101  GetFilenames(0, frmPlaylist->lstSongs->Items->Count, Playlist.get());
102 
103  Playlist->AddStrings(DropFiles);
104 
105  // get the rest of the list;
106  if (DropIndex > -1)
107  GetFilenames(DropIndex, frmPlaylist->lstSongs->Items->Count - 1, Playlist.get());
108 
109  dmRemote->DoAddFiles(Playlist.get());
110 
111  // reset position here
112 
113  // AAAACK - used to be a "magic object"
114  int NewPos = DropFiles->IndexOfObject((TObject *) true);
115  dmRemote->client->setPlaylistIndex(NewPos);
116 
117  dmRemote->PlaylistRefresh->Execute();
118 }
119 
120 void __fastcall TdmRemote::DoBind(const AnsiString& address, const AnsiString& endpoint)
121 {
122  Bind(address.c_str(), endpoint.c_str(), pszProtocolSequenceNP);
123 }
124 
125 void __fastcall TdmRemote::PauseExecute(TObject *)
126 {
127  // TODO: used to have checked update protection
128  client->pause();
129 }
130 
131 void __fastcall TdmRemote::PlayExecute(TObject *)
132 {
133  client->playSong();
134 }
135 
136 void __fastcall TdmRemote::NextExecute(TObject *)
137 {
138  SongChanging->Execute();
139  client->nextSong();
140  SongChanged->Execute();
141 }
142 
143 void __fastcall TdmRemote::NextFadeExecute(TObject *)
144 {
145  StopFade->Execute();
146  Next->Execute();
147  Play->Execute();
148 
149 }
150 
151 void __fastcall TdmRemote::PreviousExecute(TObject *)
152 {
153  SongChanging->Execute();
154  client->previousSong();
155  SongChanged->Execute();
156 }
157 
158 void __fastcall TdmRemote::StopExecute(TObject *)
159 {
160  client->stopSong();
161 }
162 
163 void __fastcall TdmRemote::Forward5Execute(TObject *)
164 {
165  client->forward5();
166 }
167 
168 void __fastcall TdmRemote::Back5Execute(TObject *)
169 {
170  client->back5();
171 }
172 
173 void __fastcall TdmRemote::VolumeUpExecute(TObject *)
174 {
175  client->volumeUp();
176  UpdateBars();
177 }
178 
179 void __fastcall TdmRemote::VolumeDownExecute(TObject *)
180 {
181  client->volumeDown();
182  UpdateBars();
183 }
184 
185 void __fastcall TdmRemote::VolumeUpMoreExecute(TObject *)
186 {
187  client->setVolume(client->getVolume() + 10);
188  UpdateBars();
189 }
190 
191 void __fastcall TdmRemote::VolumeDownMoreExecute(TObject *)
192 {
193  client->setVolume(client->getVolume() - 10);
194  UpdateBars();
195 }
196 
197 void __fastcall TdmRemote::PlaylistStartExecute(TObject *)
198 {
199  SongChanging->Execute();
200  client->startPlaylist();
201  SongChanged->Execute();
202 }
203 
204 void __fastcall TdmRemote::PlaylistEndExecute(TObject *)
205 {
206  SongChanging->Execute();
207  client->playlistEnd();
208  SongChanged->Execute();
209 }
210 
211 void __fastcall TdmRemote::DeletePlayListExecute(TObject *)
212 {
213  client->deletePlaylist();
214  PlaylistRefresh->Execute();
215 }
216 
217 void __fastcall TdmRemote::StopFadeExecute(TObject *)
218 {
219  client->stopWithFade();
220 }
221 
222 void __fastcall TdmRemote::StopAfterCurrentExecute(TObject *)
223 {
224  client->stopAfterCurrent();
225 }
226 
227 void __fastcall TdmRemote::SetVolume0Execute(TObject *)
228 {
229  client->setVolume(0);
230  UpdateBars();
231 
232 }
233 
234 void __fastcall TdmRemote::SetVolume100Execute(TObject *)
235 {
236  client->setVolume(255);
237  UpdateBars();
238 }
239 
240 void __fastcall TdmRemote::ShuffleExecute(TObject *)
241 {
242  // shuffle / repeat status only works in very recent versions,
243  // so always do for older
244  if ( (client->winampVersion() < 0x2604) || (Shuffle->Checked == client->getShuffle() ) )
245  client->toggleShuffle();
246 }
247 
248 void __fastcall TdmRemote::RepeatExecute(TObject *)
249 {
250  // shuffle / repeat status only works in very recent versions,
251  // so always do for older
252  if ( (client->winampVersion() < 0x2604) || (Repeat->Checked == client->getRepeat() ) )
253  client->toggleRepeat();
254 }
255 
256 void __fastcall TdmRemote::PlayFromStartExecute(TObject *)
257 {
258  SongChanging->Execute();
259  client->playlistStart();
260  SongChanged->Execute();
261 }
262 
263 void __fastcall TdmRemote::ZeroExecute(TObject *)
264 {
265  client->setVolume(0);
266  UpdateBars();
267 
268 }
269 
270 void __fastcall TdmRemote::HalfExecute(TObject *)
271 {
272  client->setVolume(128);
273  UpdateBars();
274 }
275 
276 void __fastcall TdmRemote::FullExecute(TObject *)
277 {
278  client->setVolume(255);
279  UpdateBars();
280 
281 }
282 
283 void __fastcall TdmRemote::ViewToolBarExecute(TObject *)
284 {
285  // need to undock
286  frmCommands->Visible = !frmCommands->Visible;
287  ViewToolBar->Checked = frmCommands->Visible;
288 }
289 
290 void __fastcall TdmRemote::ViewPlaylistExecute(TObject *)
291 {
292  frmPlaylist->Visible = !frmPlaylist->Visible;
293  ViewPlaylist->Checked = frmPlaylist->Visible;
294 }
295 
296 void __fastcall TdmRemote::ViewVolumeExecute(TObject *)
297 {
298  frmSettings->Visible = !frmSettings->Visible;
299  ViewVolume->Checked = frmSettings->Visible;
300 }
301 
302 void __fastcall TdmRemote::AutoloadExecute(TObject *)
303 {
304  client->toggleAutoload();
305  Autoload->Checked = client->getAutoload();
306 }
307 
308 void __fastcall TdmRemote::EQOnExecute(TObject *)
309 {
310 
311  client->toggleEQOn();
312  EQOn->Checked = client->getEQOn();
313 
314 }
315 
316 void __fastcall TdmRemote::DetailsExecute(TObject *)
317 {
318  TfrmDetails *DetailsForm = new TfrmDetails(NULL);
319  try
320  {
321  DetailsForm->ShowModal();
322  }
323  __finally
324  {
325  delete DetailsForm;
326  }
327 }
328 
329 void __fastcall TdmRemote::PreviousFadeExecute(TObject *)
330 {
331  StopFade->Execute();
332  Previous->Execute();
333  Play->Execute();
334 
335 }
336 
337 void __fastcall TdmRemote::SongChangingExecute(TObject *)
338 {
339  // if special actions required, this action can do them
340  // if the fade on stop is checked, the playing status needs to be cached
341  if (ChangeFade->Checked)
342  StopFade->Execute();
343 
344 }
345 
346 void __fastcall TdmRemote::SongChangedExecute(TObject *)
347 {
348  // if special actions required, this action can do them
349  if ( (ChangeFade->Checked) && (PlaybackStatus() == WA_PLAYING) )
350  Play->Execute();
351 }
352 
353 void __fastcall TdmRemote::NewSongExecute(TObject *)
354 {
355  // gets the index from the playlist form
356  SongChanging->Execute();
357  // TOD implement getting this
358  client->setPlaylistIndex(frmPlaylist->lstSongs->ItemIndex);
359  Play->Execute();
360  SongChanged->Execute();
361 
362 }
363 
364 void __fastcall TdmRemote::PlaylistRefreshExecute(TObject *)
365 {
366 
367  frmPlaylist->lstSongs->Items->BeginUpdate();
368  try
369  {
370  try
371  {
372 
374 
375  LastLength = client->getPlaylistLength();
376  LastIndex = CurrentIndex;
377  CurrentIndex = client->getCurrentPlayPosition();
378 
379  frmPlaylist->lstSongs->Items->Clear();
380 
381  std::auto_ptr<TStringList> SongList(new TStringList());
382 
383  std::string list = client->getStringList(IPC_GETPLAYLISTTITLE);
384 
385  SongList->Clear();
386  SongList->Text = list.c_str();
387 
388  frmPlaylist->lstSongs->Items->Assign(SongList.get());
389 
390 
391  }
392  catch( ERPCException &E)
393  {
394  frmPlaylist->lstSongs->Items->Text = AnsiString().sprintf(sListUnobtainable.c_str(), E.what());
395  }
396 
397  }
398  __finally
399  {
400 
401  frmPlaylist->lstSongs->Items->EndUpdate();
402  }
403 }
404 
405 void __fastcall TdmRemote::PlaylistRefreshStatsExecute(TObject *)
406 {
407 
408 
409  int SongS = 0;
410  int PosMS = 0;
411 
412  client->getTimes(SongS, PosMS);
413 
414  if ((SongS) && (!frmPlaylist->Dragging))
415  frmPlaylist->pbSongPos->Position = (frmPlaylist->pbSongPos->Max * PosMS) / (SongS * 1000);
416 
417  if (frmPlaylist->lstSongs->Items->Count > 1)
418  frmPlaylist->pbListPos->Position = (frmPlaylist->pbListPos->Max * CurrentIndex) /
419  (frmPlaylist->lstSongs->Items->Count - 1);
420  else
421  frmPlaylist->pbListPos->Position = 0;
422 
423  // time
424  frmPlaylist->sbPlaylist->Panels->Items[1]->Text = TimeToStr(Time());
425  // current song length
426  frmPlaylist->sbPlaylist->Panels->Items[3]->Text = TimeToStr((float) SongS / SecsPerDay);
427 
428 }
429 
430 void __fastcall TdmRemote::AboutExecute(TObject *)
431 {
432  if (!frmAbout)
433  {
434  frmAbout = new TfrmAbout(this);
435  try
436  {
438  frmAbout->ShowModal();
439  }
440  __finally
441  {
442  delete frmAbout;
443  frmAbout = NULL;
444  }
445  }
446  else
447  {
448  frmAbout->Show();
449  frmAbout->BringToFront();
450  }
451 }
452 
453 void __fastcall TdmRemote::AddDirectoryExecute(TObject *)
454 {
455  // attached to menu entry
456 }
457 void __fastcall TdmRemote::AddPlayIistExecute(TObject *)
458 {
459 AnsiString str;
460 AnsiString commandstr;
461 
462  odlgMain->FileName = "";
463 
464  // TODO this is poor style
465  if (false /* looking for playlist */){
466  odlgMain->Filter = sPlayListFiles;
467  }
468  else{
469  odlgMain->Filter = sAllFiles;
470  }
471 
472  if (odlgMain->Execute())
473  {
474 
475  std::auto_ptr<TStringList> Files(new TStringList);
476  // sort strings by name, for now
477  Files->Sorted = true;
478 
479  Files->Assign(odlgMain->Files);
480 
481  DoAddFiles(Files.get());
482  PlaylistRefresh->Execute();
483  } // if
484 }void __fastcall TdmRemote::DownExecute(TObject *)
485 {
486  // TODO referenced from menu
487 }
488 
489 void __fastcall TdmRemote::DownMoreExecute(TObject *)
490 {
491  // TODO referenced from menu
492 }
493 
494 void __fastcall TdmRemote::EndExecute(TObject *)
495 {
496  // TODO referenced from menu
497 }
498 
499 void __fastcall TdmRemote::ExitExecute(TObject *)
500 {
501  Application->Terminate();
502 }
503 
504 void __fastcall TdmRemote::LocateServersExecute(TObject *)
505 {
506  AnsiString EndPoint = frmMain->ebEndPoint->Text;
507  AnsiString Address = frmMain->ebAddress->Text;
508 
509  // TODO - should be done via an interface
510  // block UI timer
511  frmMain->timerMain->Enabled = false;
512  UnBind();
513  TfrmServers * ServersForm = new TfrmServers(this);
514  try
515  {
516  ServersForm->ebEndPoint->Text = EndPoint;
517  ServersForm->ShowModal();
518  if (ServersForm->ModalResult != mrOk)
519  {
520  //restore
521  frmMain->ebEndPoint->Text = EndPoint;
522  frmMain->ebAddress->Text = Address;
523  }
524  else
525  {
526  frmMain->ebEndPoint->Text = ServersForm->EndPoint;
527  frmMain->ebAddress->Text = ServersForm->Address;
528 
529  }
530  }
531  __finally
532  {
533  DoBind(ServersForm->Address, ServersForm->EndPoint);
534  delete ServersForm;
535  // perform UI update
536  frmMain->MainTimer(this);
537  frmMain->timerMain->Enabled = true;
538  }
539 }
540 
541 void __fastcall TdmRemote::PlaceOnTrayExecute(TObject *)
542 {
543  // TODO referenced from menu
544 
545 }
546 
548 {
549  // TODO referenced from menu
550 }
551 
552 void __fastcall TdmRemote::ShowMainFormExecute(TObject *)
553 {
554 
555 #ifndef IDANI_CLOSE
556  #define IDANI_CLOSE 2
557 #endif
558 #ifndef IDANI_CAPTION
559  #define IDANI_CAPTION 3
560 #endif
561 
562  ShowWindow(Application->Handle, SW_SHOW);
563 
564  DWORD dwExStyle = GetWindowLong(Application->Handle, GWL_EXSTYLE);
565  dwExStyle ^= WS_EX_TOOLWINDOW;
566  SetWindowLong(Application->Handle, GWL_EXSTYLE, dwExStyle);
567 
568  TRect FromRect, ToRect;
569  FromRect = TRect(Screen->Width - 16, Screen->Height, Screen->Width, Screen->Height - 16);
570 
571  ToRect = frmMain->BoundsRect;
572 
573  HRGN HideRegion = CreateRectRgn(0,0,1,1);
574  SetWindowRgn(frmMain->Handle, HideRegion, false);
575 
576  frmMain->Show();
577 
578  DrawAnimatedRects(frmMain->Handle, IDANI_CAPTION, &FromRect, &ToRect);
579 
580  SetWindowRgn(frmMain->Handle, NULL, true);
581 
582  // dodge here
583  Application->Restore();
584 
585 }
586 
587 void __fastcall TdmRemote::StartExecute(TObject *)
588 {
589  // TODO referenced from menu
590 
591 }
592 
593 void __fastcall TdmRemote::UpExecute(TObject *)
594 {
595  // TODO referenced from menu
596 }
597 
598 void __fastcall TdmRemote::UpMoreExecute(TObject *)
599 {
600  // TODO referenced from menu
601 }
602 
603 
604 void __fastcall TdmRemote::PlaylistDragDrop(int dropIndex, int currentPos)
605 {
606  int i;
607 
608  bool CurrentSong;
609  int NewPos;
610 
611  std::auto_ptr<TStringList> TopList(new TStringList());
612  std::auto_ptr<TStringList> MiddleList(new TStringList());
613  std::auto_ptr<TStringList> BottomList(new TStringList());
614 
615  /* rather wasteful, as we have to get all the undeleted items and resend them to winamp*/
616 
617 
618  for (i = 0 ; i < FPlaylistForm->lstSongs->Items->Count; i++)
619  {
620  std::string filename = client->getPlayListItem(i, false);
621 
622  CurrentSong = i == currentPos;
623 
624  if (FPlaylistForm->lstSongs->Selected[i])
625  {
626  MiddleList->AddObject(filename.c_str(), (TObject *) CurrentSong);
627  }
628  else if (i < dropIndex)
629  {
630  TopList->AddObject(filename.c_str(), (TObject *) CurrentSong);
631  }
632  else
633  {
634  BottomList->AddObject(filename.c_str(), (TObject *) CurrentSong);
635  }
636  } // for
637 
638  // rebuild list
639  TopList->AddStrings(MiddleList.get());
640  TopList->AddStrings(BottomList.get());
641  // reset position
642 
643  DoAddFiles(TopList.get());
644 
645  NewPos = TopList->IndexOfObject((TObject *) true);
646 
647  PlaylistRefresh->Execute();
648 
649  if (NewPos >= 0)
650  client->setPlaylistIndex(NewPos);
651 
652 }
653 
654 
655 void __fastcall TdmRemote::SetSongPosition(int pos, int width)
656 {
657 
658  int SongS = 0, PosMS;
659  client->getTimes(SongS, PosMS);
660  client->setTime((1000 * SongS * pos) / width);
661 
662 }
663 
664 
665 
666 void __fastcall TdmRemote::SetVolume(int volume)
667 {
668  client->setVolume(volume);
669 }
670 
671 
672 void __fastcall TdmRemote::SetBalance(int balance)
673 {
674  client->setPanning(balance);
675 }
676 
677 
678 void __fastcall TdmRemote::BarChange(int index, byte position)
679 {
680 
681  client->setEQData(index, position );
682 }
683 
684 
685 void __fastcall TdmRemote::UpdateBars()
686 {
687 
688  if (FPlaylistForm)
689  {
690  vector<int> bands;
691  for (int i = 0; i < 11; i++)
692  {
693  bands.push_back(dmRemote->client->getEQData(i));
694  }
695 
696  FSettingsForm->UpdateBars(dmRemote->client->getAutoload(),
697  dmRemote->client->getEQOn(),
698  bands);
699  }
700 }
701 
702 void __fastcall TdmRemote::UpdateValues()
703 {
704 
705  Shuffle->Checked = (client->winampVersion() >= 0x2604) && client->getShuffle();
706  Repeat->Checked = (client->winampVersion() >= 0x2604) && client->getRepeat();
707 
708  frmSettings->tbVolume->Position = client->getVolume();
709  frmSettings->tbBalance->Position = client->getPanning();
710 
711  UpdateBars();
712 
713  dmRemote->PlaylistRefreshStats->Execute();
714 
715 
716 }
717 
719 {
720  return client->getPlaybackStatus();
721 }
722 
723 std::string __fastcall TdmRemote::WinampVersionString()
724 {
726 }
727 
728 std::string __fastcall TdmRemote::CurrentSong()
729 {
730  int index = client->getCurrentPlayPosition();
731  std::string title = "";
732  if (index > 0)
733  title = client->getPlayListItem(index, true);
734 
735  return title;
736 }
737 
738 void __fastcall TdmRemote::GetPlaylistState(int& length, int & index)
739 {
740  index = client->getCurrentPlayPosition();
741  length = client->getPlaylistLength();
742 }
743 
744 void __fastcall TdmRemote::DoDeleteSelected(void)
745 {
746  int i;
747  WinampRemote::Utils::CursorGuard ci(crAppStart);
748  std::auto_ptr < TStringList > StringList(new TStringList);
749 
750  /* rather wasteful, as we have to get all the undeleted items and resend them to winamp*/
751  std::string list = client->getStringList(IPC_GETPLAYLISTFILE);
752 
753  StringList->Text = list.c_str();
754 
755  for (i = FPlaylistForm->lstSongs->Items->Count - 1; i >= 0; i--)
756  {
757  if (FPlaylistForm->lstSongs->Selected[i])
758  {
759 
760  StringList->Delete(i);
761  if (i < CurrentIndex)
762  CurrentIndex--;
763  }
764  } // for
765 
766  // add remaining
767  dmRemote->DoAddFiles(StringList.get());
768  // reset position
769 
770  dmRemote->client->setPlaylistIndex(CurrentIndex);
771 
772  dmRemote->PlaylistRefresh->Execute();
773 
774 }
775 
776 void __fastcall TdmRemote::DataModuleCreate(TObject *)
777 {
779 }
780 
781 void __fastcall TdmRemote::DataModuleDestroy(TObject *)
782 {
783  delete client;
784 }
785 
786 void __fastcall TdmRemote::registerForm(TForm * aForm)
787 {
788  // TODO PMM - this could be made generic in a couple of ways
789  {
790  TfrmPlaylist * form = dynamic_cast<TfrmPlaylist *>(aForm);
791  if (form)
792  {
793  hookEvents(aForm, FPlaylistForm);
794  FPlaylistForm = form;
795  }
796  }
797  {
798  TfrmMain * form = dynamic_cast<TfrmMain *>(aForm);
799  if (form)
800  {
801  hookEvents(aForm, FMainForm);
802  FMainForm = form;
803  }
804  }
805  {
806  TfrmSettings * form = dynamic_cast<TfrmSettings *>(aForm);
807  if (form)
808  {
809  hookEvents(aForm, FSettingsForm);
810  FSettingsForm = form;
811  }
812  }
813  {
814  TfrmCommands * form = dynamic_cast<TfrmCommands *>(aForm);
815  if (form)
816  {
817  hookEvents(aForm, FCommandsForm);
818  FCommandsForm = form;
819  }
820  }
821 }
822 
823 void __fastcall TdmRemote::unRegisterForm(TForm * aForm)
824 {
825  if (aForm == FPlaylistForm)
826  FPlaylistForm = NULL;
827  if (aForm == FMainForm)
828  FMainForm = NULL;
829  if (aForm == FSettingsForm)
830  FSettingsForm = NULL;
831 }
832 
833 void __fastcall TdmRemote::HideOnStartExecute(TObject *Sender)
834 {
835  // TODO attach to UI and implement
836 }
837 
838 
839 void __fastcall TdmRemote::RestoreOnStartExecute(TObject *Sender)
840 {
841  // TODO attach to UI and implement
842 }
843 
844 
845 void __fastcall TdmRemote::ChangeFadeExecute(TObject *Sender)
846 {
847  // TODO attach to UI and implement
848 }
849 
850 
851 void __fastcall TdmRemote::restoreForms(WinampRemote::Config::ClientConfig & config)
852 {
853 
854  // set up the commands form
855  {
856  const TPoint CommandsTL = config.CommandsPos();
857 
858  frmCommands->Top = CommandsTL.y;
859  frmCommands->Left = CommandsTL.x;
860 
861  if (config.CommandsVisible())
862  ViewToolBarExecute(this);
863  }
864 
865 
866 
867  // set up the commads form
868  {
869  const TPoint VolumeTL = config.VolumePos();
870 
871  frmSettings->Top = VolumeTL.y;
872  frmSettings->Left = VolumeTL.x;
873 
874  if (config.VolumeVisible())
875  ViewToolBarExecute(this);
876  }
877 
878 
879  {
880  const TRect PlaylistBounds = config.PlaylistPos();
881 
882  frmPlaylist->BoundsRect = PlaylistBounds;
883  if (config.PlaylistVisible())
884  ViewPlaylistExecute(this);
885 
886  }
887 
888 
889 }