Avatar billede trine_h Nybegynder
13. november 2003 - 17:34 Der er 24 kommentarer

Kald af postmessage

Nyt spørgsmål:

Hvordan kalder man postmessage fra en anden klasse end den der nedarver fra cwnd?

Måske kunne en komme med et eksempel på en bruger defineret besked som bliver kaldt fra en anden klasse end den der nedarver fra cwnd.
Avatar billede trine_h Nybegynder
13. november 2003 - 17:52 #1
Her er lidt kode...
I window klassen som nedarver fra cwnd har jeg følgende kode:
file.hwndNotify = this->m_hWnd;   
cTimerProc.JumpToTicks(&file, (int) 0);

I en anden klasse er metoden JumpToTicks:
void CTimerProc::JumpToTicks(MIDI_FILE * file, int iNumTicks)

Fra JumpToTicks metoden vil jeg gerne sende følgende besked:
PostMessage(file->hwndNotify, WM_MIDI_MSG, 0, (LPARAM) dwMessage);
Avatar billede driis Nybegynder
13. november 2003 - 17:59 #2
Det skulle du gerne kunne gøre direkte - du skal inkludere <windows.h> i din CTimerProc header.
Avatar billede trine_h Nybegynder
13. november 2003 - 18:11 #3
øh er det ikke kun ved cprogrammering - jeg bruger mfc klasserne
Avatar billede jpk Nybegynder
13. november 2003 - 18:24 #4
Du kan sende en pointer/reference med til det vindue du vil sende messages til.
Hvis det er dit main window, kan du også bruge AfxGetMainWnd() til at få fat i det...
Avatar billede trine_h Nybegynder
13. november 2003 - 18:50 #5
afxGetMainWnd() metoden har jeg fat i - men gider du give et eksempel på pointer/reference metoden
Avatar billede trine_h Nybegynder
13. november 2003 - 19:47 #6
Jeg forsøger at lave en brugerdefineret postmessage på følgende måde, men får en masse fejl - er der nogen der kan gennemskue hvad problemet er?

afx_msg void OnWmMidiTicks (WPARAM wParam, LPARAM lParam);



BEGIN_MESSAGE_MAP( CStartWnd, CFrameWnd )
    ON_REGISTERED_MESSAGE(WM_MIDI_TICKS, OnWmMidiTicks)



LRESULT CStartWnd::OnWmMidiTicks(WPARAM wParam, LPARAM lParam)
{
    // do something useful

    return (LRESULT) 0;
};
Avatar billede trine_h Nybegynder
13. november 2003 - 19:57 #7
okey en fejl havde sneget sig ind (måske flere !) : følgende kompilerer:



afx_msg LRESULT OnWmMidiTicks (WPARAM wParam, LPARAM lParam);

EGIN_MESSAGE_MAP( CStartWnd, CFrameWnd )
    ON_MESSAGE(WM_MIDI_TICKS, OnWmMidiTicks)

LRESULT CStartWnd::OnWmMidiTicks(WPARAM wParam, LPARAM lParam)
{
    // do something useful

    return (LRESULT) 0;
};


men når jeg indsætter følgende:
CWnd* cWnd = AfxGetMainWnd();
cWnd->PostMessage(WM_MIDI_TICKS, 0, (LPARAM) pfile->fTicks);

opstår følgende runtime fejl:
unhandled exception
Avatar billede bertelbrander Novice
13. november 2003 - 20:20 #8
Returnerer AfxGetMainWnd() en NULL pointer?
Hvornår deallokeres pfile?
Hvad er pfile->fTicks?
Hvor får du runtime fejl?
Avatar billede trine_h Nybegynder
13. november 2003 - 20:39 #9
Korrekt - AfxGetMainWnd() returnerer NULL - mit problem er derfor stadig at jeg ikke ved hvordan man kalder Postmessage fra en anden klasse end den mainwindow er defineret i

jpk skrev : Du kan sende en pointer/reference med til det vindue du vil sende messages til.
gider én give et eksempel på pointer/reference metoden?

file->hwndNotify er af typen HWND
Avatar billede bertelbrander Novice
13. november 2003 - 20:46 #10
Hvis AfxGetMainWnd() returnerer NULL må det være fordi du kalder den uden at have et main-vindue, f.ex. fordi du kalder den før eller efter at du har lavet vinduet, og så giver det ikke mening at forsøge at sende en besked til vinduet.

Sender du beskeden fra en anden tråd end hovedtråden?
Avatar billede bertelbrander Novice
13. november 2003 - 20:56 #11
f.ex. fordi du kalder den før eller efter at du har lavet vinduet

skulle være:

f.ex fordi du kalder den før du har lavet vinduet eller efter at du har lukket det.
Avatar billede trine_h Nybegynder
13. november 2003 - 21:03 #12
MainWindow klassen oprettes således:
CStartWnd::CStartWnd() {
    Create( NULL, "Figur-i-vindue" );
static char szFileName[] = "c://test.mid";
    ZeroMemory(&file, sizeof(MIDI_FILE));
    file.hMidiOut = cMidiUtility.AabenMidiOutDevice(0);
    file.hwndNotify = this->m_hWnd;   
timeGetDevCaps(&timecaps, sizeof(TIMECAPS));
              file.uResolution = timecaps.wPeriodMin;
cTimerProc.JumpToTicks(&file, (int) 0);
            file.fTempoAdjust = 1;
                    // Set the timer and start it going
                file.bLoaded = TRUE;
              timeBeginPeriod(file.uResolution);
              file.bGoing = TRUE;
              file.uTimerID = timeSetEvent(file.uResolution, 0,cTimerProc.TimerProc,(DWORD) &file, TIME_PERIODIC);
   

Den klasse (som indeholder jumptoticks) indeholder en multimedia timer -

er det følgende linie der laver vinduet - så bliver den altså kaldt før jeg kalder metoden jumptoticks som efterfølgende udfører postmessage metoden:

Create( NULL, "Figur-i-vindue" );
Avatar billede bertelbrander Novice
13. november 2003 - 21:53 #13
AfxGetMainWnd() returnerer m_pMainWnd fra din applikation, som for MFC normalt er en klasse nedarvet fra CWinApp.

Så hvis du selv create'er hoved vinduet uden for applikationen (og ikke sætter applikationens m_pMainWnd) vil AfxGetMainWnd() returnere NULL.

Så du er nødt til at give den klasse der kalder PostMessage() en pointer til det vindue den skal sende til. Det kan man gøre med en beskidt global pointer, eler ved at give class'en en pointer til hoved vinduet, f.ex i constructoren.
Avatar billede trine_h Nybegynder
13. november 2003 - 22:19 #14
I mit hovedvindue har jeg følgende initialisering - sætter det ikke m_painWnd?
BOOL CStart::InitInstance() {
    m_pMainWnd = new CStartWnd;    //
    m_pMainWnd->ShowWindow( m_nCmdShow );
    m_pMainWnd->UpdateWindow();
    return TRUE;
}


Gider du give et eksempel på hvordan jeg giver en pointer fra hvoedvinduet feks igennem konstruktøren på den klasse og på hvordan jeg bruger denne til at kalde postmessage?`
Avatar billede trine_h Nybegynder
13. november 2003 - 22:38 #15
også meget gerne hvordan man opretter en "beskidt" global pointer? så skal du få pointene og mange tak for hjælpen forresten
Avatar billede bertelbrander Novice
13. november 2003 - 23:43 #16
Jo, koden ovenfor sætter m_pMainWnd, men ved nærmere eftersyn;

AfxGetMainWnd() giver dig main-vinduet for den thread der kalder den. Så hvis du kalder den AfxGetMainWnd fra en anden tråd en main vil du få en NULL pointer (medmindre denne tråd har lavet en vindue, og sat m_pMainWnd).

Du har sansynligvis en instans af CStart, du kan lave en

extern CStart whateever;

i en headerfil der kan ses af funktionen der skal sende beskeden.

Når du så skal sende beskeden kan du bruge:

whatever.m_pMainWnd->PostMessage(...);

Man bør i øvrigt bruge PostThreadMessage(...) til at sende beskeder mellem flere thread's.
Avatar billede trine_h Nybegynder
14. november 2003 - 09:26 #17
Her er header filerne i projektet - hvis du gider at vise hvor "extern CStart .." skal sættes ind, for uanset hvad jeg gør får "redefinition error"

miditest.h:


#ifndef GL_TIME
#define GL_TIME
#include "MidiColors.h"
#endif
//char                  szBuffer[MAX_PATH];
extern "C"
{
char * LoadMidiFile(char * szFileName, MIDI_FILE * pfile);
}

class CStart : public CWinApp {        // Hovedklasse
public:
    virtual BOOL InitInstance();
};


MidiColors.h

#include <mmsystem.h>

CTimerProc.h: (som er den klasse postmessage beskeden skal sendes fra)

//#include "StdAfx.h"
#ifndef GL_TIME
#define GL_TIME
#include "MidiColors.h"
#endif
//#ifndef START
//#define START
//#include "miditest.h"
//#endif

class CTimerProc {
  private:
    public:
      CTimerProc();
   
    //  ~CTimerProc();
    // static BYTE NextByte(BYTE **ppBuffer);
   
void JumpToTicks(MIDI_FILE * pfile, int iNumTicks);
static void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
};
Avatar billede bertelbrander Novice
14. november 2003 - 22:47 #18
Du bør indsætte din "extern CStart ..." i miditest.h efter definitionen af class'en, dvs i bunden af filen.
Avatar billede trine_h Nybegynder
15. november 2003 - 10:54 #19
okey - jeg har nu lavet en instans af CStart og kalder den på følgende måde i CTimerProc klassen

CWnd* cWnd = Starten.m_pMainWnd;
if (!cWnd == NULL)
{
cWnd->PostMessage(WM_PAINT, 0, (LPARAM) pfile->fTicks);
}

Og cWnd returnerer stadig NULL ! Hvis du gad kigge det igennem, kunne jeg evt. maile projektet til dig? - det er ikke ret stort :) det ville være super
Avatar billede bertelbrander Novice
15. november 2003 - 11:52 #20
Linien "if (!cWnd == NULL)"

Bør nok være:
if(cWnd == NULL)
eller
if(!cWnd)

Jeg har desværre ikke tid i dag.
Avatar billede bertelbrander Novice
15. november 2003 - 13:00 #21
Det er muligt at din timer-proc bliver kaldt inden du har sat m_pMainWnd, da du kalder timeSetEvent() inden du assigner til m_pMainWnd.

Bliver hoved vinduet oprettet?

Jeg er først tilbage i morgen aften, hvis du ikke har det til at virke inden, må du godt maile mig projektet, men email adresse står på min minisite (klik på mit navn ude til venste og vælg "vis brugerinfo").
Avatar billede trine_h Nybegynder
20. november 2003 - 20:21 #22
bertel du skal selvfølgelig have pointene - læg et svar - og tak for hjælpen
Avatar billede bertelbrander Novice
20. november 2003 - 20:46 #23
Fik du det til at spille?

Jeg forsøger at undgå point.
Avatar billede trine_h Nybegynder
27. november 2003 - 13:56 #24
Hov jeg har været væk den sidste uge - derfor det sene svar - ja det du sendte virkede i hvertfald - men jeg er ikke kommet videre siden.. hej hej
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester