Red de conocimiento informático - Aprendizaje de programación - ¿Cuánto tiempo le toma a mfc ejecutar un bucle for?

¿Cuánto tiempo le toma a mfc ejecutar un bucle for?

El ciclo de ejecución de un subproceso generalmente finaliza después de que regresa la función del subproceso.

Los pasos de ejecución del programa MFC (principalmente inicialización):

Abra un proyecto MFC APPWizard (exe) y siga sus pasos de ejecución. Puede encontrar que está organizado en el siguiente orden:

1. Definición de variable global en CXXApp (variable global definida antes de la función WinMain())

CXXApp theApp

2. Llame al constructor CXXApp (por supuesto, cuando crea una clase, primero llamará a su propio constructor y WinMain() aún no se ha ejecutado. ¿No es extraño? En realidad, es similar a la variable A en el ejemplo anterior.)

CXXApp ::CXXApp(){}

3. Ingrese la función WinMain (_tWinMain es una macro con el valor Winmain) (esta función no está escrita por nosotros mismos, está oculto en un archivo relativamente oculto, d:/program files/Microsoft Visual Studio/vc98/MFC/src/Winmain ..)

_tWinMain(){}(Si usted. mira su definición, #define _tWinMain WinMain , de hecho son iguales).

4. Inicialización completa: incluido el registro de clase de ventana, generación, visualización y actualización de ventanas.

pThread-& gt;Initiatinstance() (Dado que InitInstance es una función virtual, esta vez se llama a la función InitInstance() de la clase derivada, que es la función que ves en la App).

Para programas MFC, mainframes, vistas, barras de herramientas, Controlbar, etc. Todas son ventanas, por lo que se registran, crean, muestran, etc. las siguientes ventanas. Esto se debe llamar repetidamente, una ventana a la vez.

(1) Registrar clase de ventana: AfxEndDeferRegisterClass() (equivalente a la función RegisterClass() en SDK)

(2) Crear ventana: cmaiframe::pre Create window()/ /Llamarlo repetidamente nos da la oportunidad de modificar las propiedades de la ventana.

CFrameWnd::Create()

(3) Ciclo de mensajes: PumpMessage()

Suplemento 1:

En MFC, porque Implica la definición de la clase (ventana), se requieren más pasos al definir variables globales.

Si la variable global implica una definición de clase (similar a la definición de tipo en C), debe seguir los siguientes pasos (tome la clase de ventana de MFC como ejemplo, que se usa a menudo en el SDK y ha escrito funciones usando la API que todos deberían saber).

1. Diseñar una clase de ventana

2. Registrar la clase de ventana

3. Crear una ventana

4. la ventana

5. Circulación de información

Suplemento 2: Esta lección describe la ubicación del archivo fuente de las funciones MFC.

Directorio raíz

Busque la ubicación donde instaló MFC en VC98, por ejemplo: d:/archivos de programa/Microsoft Visual Studio/VC98/MFC en mi computadora. Las siguientes son rutas relativas. Busque la carpeta SRC en la carpeta MFC en el directorio de instalación. El código fuente de MFC se encuentra en SRC.

1. Encuentre la población de WinMain:

Ruta: MFC | appmodule.cpp:

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance

LPTSTR lpCmdLine, int nCmdShow)

{

//Llamar a WinMain compartido/exportado

Return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);< / p>

}

Nota: (#define _tWinMain WinMain)

2. Para objetos o variables globales, cuando el programa se está ejecutando, es decir, cuando la función WINMAIN está en ejecución. cargado, se han asignado objetos o variables globales con memoria y valores iniciales. (La clave para comprender el constructor CTEAPP:CTEAPP() antes de ejecutar WinMain)

So:CTEApp theApp->cte app::cte app(){}->_tWinMain(){}

Descripción: Cada programa MFC tiene solo una clase (clase de aplicación) derivada de la clase WinApp, y solo un objeto instanciado de la clase de aplicación, que representa la aplicación misma. En los programas WIN32, esto significa que la aplicación está representada por la función de entrada WINMAIN (identificada por la identificación del número de caso de la aplicación). En una aplicación basada en MFC, se genera un objeto de aplicación para representar de forma única la aplicación.

3. Al llamar al constructor de la clase base CWinApp en el proceso de construcción del objeto de aplicación, se completa parte del trabajo de inicialización del programa, incluido el tiempo de ejecución en el constructor de CWinApp.

Constructor de CWinApp: MFC | src |

cwin app::cwin app(lpctstr lpszappname){...}/ acepta parámetros, pero el constructor CTEApp no ​​pasa explícitamente los parámetros a la clase principal. ¿Tiene cwinapp() los siguientes parámetros predeterminados:

(En la definición de la clase CWinApp, cwin app(lpctstr lpszappname = null);)

Nota: En CWinApp() función:

pThreadState->m_pCurrentWinThread = this

pmoduleestate->m_pCurrentWinApp = this

(Esto se refiere al objeto CTEApp de clase derivada, es decir, theApp )

Depuración: CTEApp theApp(-& gt;cte app::cte app())-& gt;CWinApp::CWinApp() (llame primero a la función de inicialización de la clase base)-& gt; cte app ::cte app()->_tWinMain(){}(La flecha roja indica el orden de ejecución)

4. En la función _ twinmain, llame a la función AfxWinMain() para completar su ejecución. función. (El prefijo Afx * indica que se trata de una función del marco de la aplicación y algunas funciones globales. El marco de la aplicación es un conjunto de modelos de marco que ayudan a generar aplicaciones. Algunas clases están integradas orgánicamente y podemos diseñar nuestras propias aplicaciones basadas en estas funciones de clase. ).

Ruta de la función AfxWinMain(): MFC|SRC|WINMAIN. CPP:

En la función AfxWinMain():

cwin app * pApp = AfxGetApp();

Descripción: pApp almacena un puntero a la clase derivada de WinApp puntero de objeto ( theApp ).

//_ afx win _ aplicación cwin INLINE * afx API AfxGetApp()

//{ return afxCurrentWinApp;}

Llamar a pThread-& gt; Instancia()

Descripción: pThread también apunta a la aplicación. Dado que el BOOL InitApplication() virtual en la clase base se define como una función virtual, pthread->; cuando InitInstance(), llama a la función InitInstance() de la clase derivada CTEApp.

nReturnCode = pThread->run();

Descripción: pThread->Run() completa el bucle del mensaje.

5. Clase de ventana de registro: afxendferregistersclass();

El archivo donde se encuentra la función AfxEndDeferRegisterClass(): MFC |

BOOL afx API clase afxendferregister (registro LONG FTO){...}

Descripción: Diseño de clases de ventana: varias clases de ventana predeterminadas se diseñan de antemano en MFC. Según la selección de diferentes aplicaciones, llame a la función AfxEndDeferRegisterClass() para registrar la clase de ventana seleccionada.

Depuración: aplicación cwin::aplicación cwin();-& gt;CTEApp theApp(-& gt;aplicación cte::aplicación cte())-& gt;aplicación cwin::aplicación cwin() ->cte app::cte app()->_tWinMain(){}//Ingrese al programa.

-& gt; afx winmain();-& gt; pApp-& gt; init application();-& gt; ->CTEApp::InitInstance()//Función de implementación de subclase; ->Clase AfxendDeferreRegister (longfto Register)//Registre la clase de ventana seleccionada (para la gestión de documentos, regístrese con anticipación, normalmente regístrese en PreCreateWindow)//Luego ingrese el Fase de creación de ventana (sin depuración a continuación).

6. precrear ventana():// registra principalmente la clase de ventana. Esta función se proporciona principalmente para que el programa pueda modificar los parámetros de la ventana varias veces, y esta función también se llama repetidamente.

BOOL CMainFrame::pre crear ventana(crear estructura y cs)

{

if (!CFrameWnd::PreCreateWindow(cs))

p>

Devuelve FALSO

Devuelve VERDADERO

}

Descripción:

El archivo donde se encuentra CFrameWnd: :La función PreCreateWindow() se encuentra en MFC|src|winfrm.cpp.

BOOL CFrameWnd::pre crear ventana(crear estructura y cs)

{

if (cs.lpszClass == NULL)

{

VERIFY(AfxDeferRegisterClass(AFX _ WNDFRAMEORVIEW _ REG));

//Determine si la clase de ventana del modelo afx _ wndframeview _ reg está registrada. Si no, regístrela. .

cs . lpsz class = _ afxWndFrameOrView; //Color_Window Background

//Asigne el nombre de clase de ventana registrada a cs.lpszClass

}

if((cs . estilo & amp; FWS _ ADDTOTITLE)& amp; & ampafxData.bWin4)

cs estilo | = FWS _ prefijo título; afxData.bWin4)

cs . dwex style | = WS _ EX _ client edge;

Devuelve TRUE

}

Estos incluyen :

Ventana virtual booleana de creación previa (crear estructura y ampcs); //PreCreateWindow() es una función virtual. Si una subclase lo posee, se llamará. Ésta es la característica de las funciones virtuales.

#Definir verificación (f) aserción (f)

#Definir AfxDeferRegisterClass(fClass)afxendferregisterclass(fClass)

Definir AFX_WNDFRAMEORVIEW_REG 0x00008

const TCHAR_afxWndFrameOrView[]= AFX_WNDFRAMEORVIEW //WINCORE. Archivo CPP, definido como una matriz global.

//# define AFX _ WNDFRAMEORVIEW AFX _ wnd class(" frameo rview ")

7. Crea una ventana:

Ruta de la función Crear(): MFC|SRC|WINFRM. CPP:

CFrameWnd::Create(...){

...

CreateEx(...);//Heredado de la clase principal , Llame a CWnd::CreateEx().

...

}

Ruta de la función CWnd::CreateEx(): MFC src |

BOOL CWnd::CreateEx(...){

...

If (!PreCreateWindow(cs))//Función virtual, si es sub Las clases tienen subclases de llamada.

{

publicar ncdestroy();

Devolver FALSO

}

...

HWND HWND =::CreateWindowEx(cs . estilo dwex, cs.lpszClass,

cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy ,

cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpcreateparams

...

}

Descripción: La correspondencia entre la función CreateWindowEx() y los parámetros de la estructura CREATESTRUCT nos permite modificar la apariencia deseada de la ventana modificando los miembros de la estructura cs con PreCreateWindow(cs) antes de crear la ventana. PreCreateWindow(cs))//Es una función virtual, si la subclase tiene una subclase que llama.

HWND CreateWindowEx(

DWORD dwExStyle,

LPCTSTR lpClassName,

LPCTSTR lpWindowName,

DWORD dwStyle,

int x,

int y,

int nWidth,

esta noche,

HWND hWndParent,

HMENU hMenu,

HINSTANCE hInstance,

LPVOID lpParam

);

typedef struct tagCREATESTRUCT {// cs

LPVOID lpCreateParams

HINSTANCE hInstance

HMENU hMenu

HWND hwndParent

int cy

int cx

int y;

int x;

Largo;

LPCTSTR lpszName

LPCTSTR lpszClass

DWORD dwExStyle

} CREATESTRUCT

8. Mostrar y actualizar ventanas:

clase CTEApp, en TEApp.cpp

m _ pMainWnd-& gt; MOSTRAR ventana (SW _ SHOW); // Mostrar ventana, m_pMainWnd apunta a la ventana del marco.

m _ pMainWnd-& gt; ventana de actualización(); //Ventana de actualización

Descripción: Secuencia de llamada.

Clase CTEApp: CWinApp pública{...}

Clase CWinApp: CWinThread pública{...}

Clase CWinThread: CCmdTarget pública

{

...

Público:

CWnd * m_pMainWnd

...

...

}

9. Ciclo de mensajes:

int AFXAPI AfxWinMain()

{ ...

//Realizar una inicialización específica

If (!pThread-& gt;InitInstance()){...}

//Completar la inicialización y el registro de la ventana, Creación, visualización y actualización de ventanas.

nReturnCode = pThread->run();

//Hereda el método Run() de la clase base y llama a CWinThread::Run() para completar el ciclo del mensaje.

...

}

////////////////////////// / ////////////////////////////////////////////

CWinThread::Ejecutar ()Ruta del método: MFC | thrdcore.cpp.

int CWinThread::Run()

{ ...

// fase2: Mensajes de bombeo cuando estén disponibles

Hacer/ / bucle de mensajes

{

// bombea el mensaje, pero sale en WM_QUIT

if (!PumpMessage()) // Recibe el mensaje y lo procesa.

Devolver instancia de salida();

...

} while(::PeekMessage(&m_msgCur,NULL,NULL,NULL,PM_ no eliminar ));

...

}

Descripción:

BOOL PeekMessage(,,,) descripción de la función

p>

La función PeekMessage verifica la cola de mensajes del hilo del mensaje y coloca el mensaje (si lo hay) en la estructura especificada.

Si el mensaje está disponible, el valor de retorno no es cero.

Si no hay ningún mensaje disponible, el valor de retorno es cero.

//////////////////////////////////////////// // ////////////////////

BOOL CWinThread::PumpMessage()

{

...

If (!* GetMessage(& M_msgCur, NULL, NULL, NULL)) // Recibe el mensaje.

{...}

...

//Procesar este mensaje

if (m_msgCur.message!= WM_ KICKIDLE & amp& amp PreTranslateMessage(& m_msgCur))

{

*Traducir mensaje (&m_msg cur); //Convertir mensaje (como un mensaje de teclado)

* enviar mensaje(& m _ msg cur); // Envía el mensaje a la función de devolución de llamada de la ventana para su procesamiento (en realidad, el mensaje programado es procesado por la función de respuesta de mensajes después del mapeo de mensajes)

}

Devuelve VERDADERO

}

9. Archivo y estructura visual:

Puedes pensar en la ventana de clase de vista como una ventana secundaria. de la ventana de clase CMainFram.

La clase de documento es una clase de documento.

La estructura de vista del documento separa los datos en sí de su visualización.

Clase de documento: almacenamiento y carga de datos.

Categoría de visualización: visualización y modificación de datos

10, una combinación orgánica de clase de documento, clase visual y clase de marco;

CTEApp:: en el Clase CTEApp En la función initinstance(), las clases de documentos, clases de visualización y clases de marco se organizan orgánicamente a través de plantillas de documentos.

...

CSingleDocTemplate * plantilla PDO;

pDocTemplate = nuevo CSingleDocTemplate(

IDR_mainframe,

RUNTIME_CLASS(CTEDoc),

RUNTIME_CLASS(CMainFrame), //Ventana principal del marco SDI

RUNTIME_CLASS(cte view));

AddDocTemplate (pDocTemplate); /Agregar a plantilla